var loginUrl = "https://ibsbjstar.ccb.com.cn/CCBIS/V6/STY1/CN/login.jsp";
var needLogin = true;
var billDate_comm = null;
var v6_ccb_java_funcs = {
    openHomePage: function () {
        //建设银行官网首页
        var loginText = get(loginUrl);
        context.put("loginText", loginText);
        lua_commfuns.saveHtmlAndImage("homePage")
        lua_commfuns.saveIframeHtmlAndImage("{'fQRLGIN'}", "homePageFrame")
    },
    checkProxyAvailable: function () {
        var html = context.get("loginText");
        //根据返回页面信息判断是不是代理ip异常
        if (html.contains("代理服务器没有响应") || html.contains("无法显示此页") || html.contains("Hypertext Transfer Protocol")) {
            logger.info("CCB taskKey = " + context.get(Constants.LUA_TASK_KEY) + " 代理IP异常");
            return false;
        } else {
            //如果代理没有问题，保存当前页面并返回true，进入下一步
            return true;
        }
    },
    checkTargetWebsiteAvailable: function () {
        return js_commfuns.checkFrameStatus();
    },
    checkControlAvailable: function () {
        return true;
    },
    needResetEnvironment: function () {
        context.put("proxyAvailable", true);
        return equals(context.get("currentErrorCode"), BALO_99601_10) || equals(context.get("currentErrorCode"), BALO_99601_30 || equals(context.get("currentErrorCode"),BALO_99602_40));
    },

    login: function () {
        var frameFlag = context.get("frame_id");
        var smsHtml = context.get("smsHtml");
        var login_result_html = context.get("login_result_html");
        if(needLogin){
            logger.info("任务【{}】,建设银行开始进行登录操作", context.get(LUA_TASK_KEY));
            //获取登录参数
            var userid = getLoginParams(context)[0];
            var password = context.get(Constants.LUA_TASK_TOKEN);
            logger.info("任务【{}】，建设银行登录参数获取成功，开始输入用户名密码进行登录", context.get(LUA_TASK_KEY));

            //输入用户名密码，判断输入结果
            lua_commfuns.input_username_password(userid, password);
            lua_commfuns.saveHtmlAndImage("input_username_password");
            //判断是否需要输入图片验证码
            var need_img = lua_commfuns.is_need_img_code();
            if (Boolean.valueOf(need_img)) {
                lua_commfuns.saveHtmlAndImage("is_need_img");
                //需要图片验证码
                var taskKey = context.get(LUA_TASK_KEY);
                context.put(TASK_IMG_PATH, get_image_by_id("fujiama"));
                context.put(TASK_IMG_REGEX, "[0-9]{5}");
                var imgCode = waitImgCodeBySecondsByJs(context, 60, true, 3);
                if (StringUtils.isBlank(imgCode) || imgCode.length() != 5) {
                    logger.info("任务taskKey = {}, 验证码信息：打码位数不足四位，手动补足 {}", taskKey, imgCode);
                    imgCode = waitImgCodeBySeconds(context, 60, true);
                }
                logger.info("任务taskKey = {}, 输入图片验证码，{}", taskKey, imgCode);
                //输入图片验证码
                var input_img_result = lua_commfuns.input_img_code(imgCode);
                lua_commfuns.saveHtmlAndImage("input_img_result");
                //校验用户名密码是否输入正确
                var isRightInputImg = function (input_img_result) {
                    return Boolean.valueOf(input_img_result);
                }
                var getInputImgErrorMsg = function () {
                    return "图片验证码错误";
                }
                assertTrueOrThrowException(input_img_result, isRightInputImg, getInputImgErrorMsg)
            }

            //点击登录按钮，判断可否进入首页，可否进入错误页面，可否进入短信页面，可否进入回答问题页面
            lua_commfuns.click_login_button();
            var login_result_html = lua_commfuns.saveHtmlAndImage("login_result");
            //判断页面是否渲染完全，问题，短信
            //获取frame的名称，获取frame页面内容
            var frameFlag = js_commfuns.getFrameFlag(login_result_html);
            context.put("frame_id",frameFlag);
            logger.info("任务【{}】,获取到的frame名称【{}】", context.get(LUA_TASK_KEY), frameFlag);
            var smsHtml = lua_commfuns.get_frame_html_by_id(frameFlag);
            storeDataToFile(context, smsHtml, "smsHtml.html");
            //增加页面是否渲染完成的判断
            for (var i = 0; i < 10; i++) {
                var error_msg = js_commfuns.getLoginErrorMsg(login_result_html, smsHtml);
                logger.info("任务【{}】,error_msg=【{}】", context.get(LUA_TASK_KEY), error_msg);
                if ((StringUtils.isNotBlank(error_msg) && !error_msg.contains("登录超时")) || smsHtml.contains("为让您更安全地使用网上银行，现对您当前使用的设备进行安全认证") || login_result_html.contains("中国建设银行网上银行个人登录验证") || login_result_html.contains("私密问题") || equals(Jsoup.parse(login_result_html).select("title").text(), "中国建设银行个人网上银行")) {
                    logger.info("任务【{}】,页面渲染完成", context.get(LUA_TASK_KEY));
                    break;
                } else {
                    logger.info("任务【{}】,页面渲染未完成，继续循环等待", context.get(LUA_TASK_KEY));
                    Thread.sleep(5000)
                    login_result_html = lua_commfuns.saveHtmlAndImage("login_result");
                    smsHtml = lua_commfuns.get_frame_html_by_id(frameFlag);
                }

            }
            context.put("login_result_html",login_result_html);
            context.put("smsHtml",smsHtml);
            storeDataToFile(context, smsHtml, "smsHtml.html");
        }
        //判断是否需要身份验证
        if (login_result_html.contains("中国建设银行网上银行个人登录验证") && login_result_html.contains("私密问题")) {
            var questions = new ArrayList();
            questions.add("你的出生地");
            context.put(TASK_QUESTIONS, questions);
            var answer = waitAnswerBySeconds(context, 300);
            logger.info("任务taskKey = {} 答案 {},答案的类型是{}", context.get(LUA_TASK_KEY), answer, typeof(answer));
            logger.info("任务taskKey = {}, 显示窗口", context.get(LUA_TASK_KEY));
            var result = JSON.parse(lua_commfuns.setAnster(answer));
            if (Boolean.valueOf(result.getString("simiwemti")) && Boolean.valueOf(result.getString("fangweiwenti"))) {
                lua_commfuns.clickButon();
            }
            Thread.sleep(2000);
            login_result_html = lua_commfuns.saveHtmlAndImage("answerloginResult");
            context.put("login_result_html",login_result_html);
        }
        //如果停留在短信错误页面，需要点击返回按钮
        var is_sms_error_html = lua_commfuns.get_frame_html_by_id(frameFlag);
        storeDataToFile(context, is_sms_error_html, "is_sms_error.html");
        if (is_sms_error_html.contains("您输入的短信动态口令不正确，请重新输入")) {
            //点击返回按钮
            lua_commfuns.click_sms_back_btn(frameFlag);
            var click_sms_back_btn_html = lua_commfuns.get_frame_html_by_id(frameFlag);
            storeDataToFile(context, click_sms_back_btn_html, "click_sms_back_btn.html");
        }

        //判断是否需要短信
        if (smsHtml.contains("为让您更安全地使用网上银行，现对您当前使用的设备进行安全认证")) {
            logger.info("任务【{}】,需要短信验证码", context.get(LUA_TASK_KEY));
            logger.info("建设银行 taskKey:{} 开始等待短信验证码时间{}", context.get(LUA_TASK_KEY));
            var smsCode = waitSmsCodeBySeconds(context, 120);
            logger.info("建设银行 taskKey:{} 等待短信结果{}", context.get(LUA_TASK_KEY), smsCode);
            //action开始: 校验短信验证码
            var isSmsCodeCorrectFunc = function (smsCode) {
                return StringUtils.isNotBlank(smsCode);
            }
            var getSmsCodeErrorMsgFunc = function (smsCode) {
                return "短信验证码超时"
            }
            assertTrueOrThrowException(smsCode, isSmsCodeCorrectFunc, getSmsCodeErrorMsgFunc)

            //输入短信
            set_frame_input_text_by_id("TRANSMSCODE", smsCode, frameFlag);
            //判断输入短信结果
            var inputMsg = lua_commfuns.getSmsInputResult(frameFlag);
            logger.info("任务【{}】,短信验证码输入结果为【{}】", context.get(LUA_TASK_KEY), inputMsg);
            var isRightInputSmsCodeCorrectFunc = function (inputMsg) {
                return StringUtils.isNotBlank(String.valueOf(inputMsg));
            }
            var getErrorInputSmsCodeErrorMsgFunc = function () {
                return "短信验证码错误"
            }
            assertTrueOrThrowException(inputMsg, isRightInputSmsCodeCorrectFunc, getErrorInputSmsCodeErrorMsgFunc)
            //点击确定按钮
            lua_commfuns.clickSmsButton(frameFlag);
            login_result_html = lua_commfuns.saveHtmlAndImage("smsInputResult");
            frameFlag = js_commfuns.getFrameFlag(login_result_html);
            var smsInputResult = lua_commfuns.get_frame_html_by_id(frameFlag);
            storeDataToFile(context, smsInputResult, "smsInputResult.html");

            var isLogin = false;
            for (var i = 0; i < 10; i++) {
                if (equals(Jsoup.parse(login_result_html).select("title").text(), "中国建设银行个人网上银行")) {
                    //登录成功或者短信错误，跳出
                    logger.info("任务【{}】,短信校验成功，登陆成功", context.get(LUA_TASK_KEY));
                    isLogin = true;
                    break;
                } else if (!smsInputResult.contains("return is null") && StringUtils.isNotBlank(smsInputResult) && !smsInputResult.contains("为让您更安全地使用网上银行，现对您当前使用的设备进行安全认证")) {
                    logger.info("任务【{}】,短信校验失败，登陆失败", context.get(LUA_TASK_KEY));
                    isLogin = false;
                    break;
                } else {
                    logger.info("任务【{}】，短信输入之后页面渲染未完成，继续等待", context.get(LUA_TASK_KEY));
                    Thread.sleep(5000)
                    smsInputResult = lua_commfuns.get_frame_html_by_id(frameFlag);
                    login_result_html = lua_commfuns.saveHtmlAndImage("smsInputResult");
                }
            }
            storeDataToFile(context, smsInputResult, "smsInputResult.html");

            //判断是否登录成功
            var isRightLoginCorrectFunc = function () {
                return isLogin;
            }
            var getLoginErrorMsgFunc = function (smsInputResult) {
                if (smsInputResult.contains("您输入的短信动态口令不正确，请重新输入")) {
                    needLogin = false;
                    return "短信验证码错误"
                } else if (smsInputResult.contains("您的操作已超时（短信动态口令3分钟内有效），请重新获取")) {
                    return "短信验证码超时"
                } else if (smsInputResult.contains("短信动态口令输入错误次数已超过3次，请重新获取")){
                    return "短信验证码错误"
                } else {
                    return "短信新分支"
                }

            }
            assertTrueOrThrowException(smsInputResult, isRightLoginCorrectFunc, getLoginErrorMsgFunc)
        }

        //判断是否登录成功
        var isLoginCorrectFunc = function (login_result_html) {
            return !equals(login_result_html, "") && equals(Jsoup.parse(login_result_html).select("title").text(), "中国建设银行个人网上银行");
        }
        var getLoginErrorMsgFunc = function (login_result_html) {
            return js_commfuns.getLoginErrorMsg(login_result_html, smsHtml);
        }
        assertTrueOrThrowException(login_result_html, isLoginCorrectFunc, getLoginErrorMsgFunc);
        logger.info("任务【 {} 】,登录成功。", context.get(LUA_TASK_KEY));
    },


    crawl: function () {
        //获取主页页面
        js_commfuns.get_main_html();
        //解析主页页面获取基本请求信息
        js_commfuns.parse_main_html();
        //获取信用卡列表
        js_commfuns.get_credit_card_list_html();
        //获取基本请求信息 ccb_individualUrl
        js_commfuns.get_base_info_url();
        //解析基本请求参数
        js_commfuns.parse_base_url_info();
        //开始获取借记卡列表
        debit_commfuns.get_debit_card_list_html();
        //开始解析借记卡数量
        debit_commfuns.parse_debit_card_size();
        //开始解析信用卡数量
        credit_commfuns.parse_credit_card_size();
        //构建表头
        createData();
        var data_list = context.get(ALL_DATA)
        //首先抓取借记卡信息
        var index = 0;
        for (var i = 0; i < data_list.size(); i++) {
            var creditCardAllData = data_list.get(i);
            if (creditCardAllData.getCardType().equals("借记卡")) {

                //抓取基本信息
                debit_commfuns.get_debit_card_base_info(index);
                //解析基本信息
                debit_commfuns.parse_debit_card_base_info(creditCardAllData);
                //前置跳转
                debit_commfuns.before_turn_other();
                //下载账单，截图
                debit_commfuns.down_debit_bill_html(creditCardAllData, index + 1);
                //解析账单
                //获取当前时间
                debit_commfuns.parse_debit_bill_html(creditCardAllData, index + 1, js_commfuns.get_now_date());
                //抓取帐户存款信息
                debit_commfuns.get_debit_deposit_html(creditCardAllData, index + 1);
                //解析存款信息
                debit_commfuns.parse_debit_deposit_html(creditCardAllData, index + 1);
                index = index + 1;
            }
        }

        //首先判断是否有信用卡
        if (context.get("ccb_is_exsit_credit_card") && context.get(keys.CRED_CARD_SIZE) > 0) {
            for (var i = 0; i < data_list.size(); i++) {
                var creditCardAllData = data_list.get(i);
                if (creditCardAllData.getCardType().equals("信用卡")) {
                    //抓取可用额度，现金额度等
                    credit_commfuns.get_credit_card_limit();
                    //解析额度信息
                    credit_commfuns.parse_credit_card_limit(creditCardAllData);
                    //抓取已出账单的列表信息
                    credit_commfuns.get_credit_card_done_bill_list_html();
                    //解析已出账单列表信息
                    credit_commfuns.parse_credit_card_done_bill_list_html();
                    //循环下载解析已出账单
                    var bill_size = context.get("ccb_done_bill_size");
                    //前12个月的账单格式和后面的账单格式不一致，需要单独解析
                    if (bill_size > 0) {
                        for (var j = 1; j <=12 && j < bill_size; j++) {
                            //获取一个可用的billAllData
                            var billAllData = getDoneBillAllDataHeaderData(creditCardAllData);
                            //采集账单页面
                            credit_commfuns.get_credit_done_bill_html(j);
                            //解析账单页面
                            credit_commfuns.parse_credit_done_bill_html(j, billAllData);
                            //解析分期明细
                            credit_commfuns.parse_credit_card_installments(billAllData);
                            //计算账单中的新增金额----本期新增
                            credit_commfuns.compute_bill_charges(billAllData);
                        }
                        //12个月之后的账单
                        if (bill_size > 13) {
                            for (var j = 13; j < bill_size; j++) {
                                var billAllData = getDoneBillAllDataHeaderData(creditCardAllData);
                                //采集账单页面
                                credit_commfuns.get_credit_done_bill_after12_html(j);
                                //解析账单页面，这个html没有分类信息，只能去txt中取
                                credit_commfuns.parse_credit_done_bill_after12_html(j, billAllData);
                            }
                            //获取12个月之前的账单页面
                            credit_commfuns.get_credit_after12_done_bill_txt();
                            credit_commfuns.parse_done_bill_txt_after12(creditCardAllData);
                        }
                    }
                    //处理多张卡的卡号问题
                    credit_commfuns.handle_card_baseinfo(creditCardAllData);
                    //开始处理未出账单
                    credit_commfuns.get_credit_undone_bill_txt();
                    //开始解析未出账单页面
                    credit_commfuns.parse_credit_undone_bill_txt(creditCardAllData);
                }
            }
        }
    },
    exitLogin: function () {
    },
    exit: function () {
    }
}

function getErrorMsg() {
    return "请核对用户名";
}


/**
 * 信用卡解析js方法
 */
var credit_commfuns = {
    //解析信用卡数量
    parse_credit_card_size: function () {
        try {
            logger.info("任务【{}】，开始解析信用卡数量", context.get(LUA_TASK_KEY));
            var html = context.get("creditCardListHtml");
            if (html.contains("持卡人信息记录不存在。") || html.contains("YDCA02813000") || !html.contains("信用卡查询")) {
                logger.info("任务【{}】，持卡人没有信用卡信息", context.get(LUA_TASK_KEY));
                context.put("ccb_is_exsit_credit_card", false);
            }
            var doc = Jsoup.parse(html);
            //通过css选择器获取到卡列表所在trs
            var trs = doc.select("#result_1 > tbody:nth-child(1) >tr");
            //每张卡有3行 一行是卡号 一行是人民币额度 一行是美元额度，第一行是标题，所以index从1开始
            var cardList = new ArrayList();
            for (var index = 1; index < trs.size(); index++) {
                //获取每个tr中的td
                var tds = trs.get(index).select("td");
                var cardNo = "";
                var cardBank = "";
                //如果获取卡号和开户行所在td不为null则继续解析

                if (tds.select("[name='strAcc_No']") != null && tds.select("[name='strAcc_No']") != "" && tds.select("[name='branch_code']") != null) {
                    //存放卡基本信息的map
                    var map = new HashMap();
                    //获取卡号
                    cardNo = tds.select("[name='strAcc_No']").val();
                    map.put("card_no", cardNo);
                    //获取开户行
                    cardBank = tds.select("[name='branch_code']").val();
                    map.put("card_bank", cardBank);
                    map.put("card_num_4", cardNo.substring(cardNo.length() - 4, cardNo.length()));
                    cardList.add(map);
                    logger.info("任务【{}】，抓取到的卡号【{}】，抓取到的银行【{}】", context.get(LUA_TASK_KEY), cardNo, cardBank);
                    logger.info("CCB taskKey=" + context.get(Constants.LUA_TASK_KEY) + "获取第" + index + "张信用卡信息");
                }
            }
            if (cardList.size() > 0) {
                logger.info("任务【{}】,抓取到{}张信用卡", context.get(LUA_TASK_KEY), cardList.size());
                context.put("ccb_is_exsit_credit_card", true);
                context.put(keys.CRED_CARD_SIZE, 1);
            }
            context.put("ccb_credit_cardlist", cardList);
            logger.info("任务【{}】，开始解析信用卡数量完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,解析信用卡数量异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //抓取可用额度，现金额度
    get_credit_card_limit: function () {
        try {
            logger.info("任务【{}】，开始抓取信用卡可用额度等信息", context.get(LUA_TASK_KEY));
            var card_list = context.get("ccb_credit_cardlist");
            var cardNo = "";
            if (card_list != null && card_list.size() > 0) {
                cardNo = card_list.get(0).get("card_no")
            }
            var userInfo = context.get("jsonUserInfo");
            var individualUrl = context.get("ccb_individualUrl");

            var cardUrl = "https://ibsbjstar.ccb.com.cn" + individualUrl + "&isAjaxRequest=true&TXCODE=XE1111&USERID=%s&BRANCHID=%s&SKEY=%s&CrCrd_CardNo=%s";
            cardUrl = String.format(cardUrl, userInfo.getString("USERID"), userInfo.getString("BRANCHID"), userInfo.getString("SKEY"), cardNo);
            var json = ajax_get(cardUrl);
            storeDataToFile(context, json, "credit_card.html");
            context.put("ccb_credit_limit_html", json);
            logger.info("任务【{}】，抓取信用卡可用额度等信息完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,抓取信用卡额度信息异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //解析信用卡可用额度信息
    parse_credit_card_limit: function (creditCardAllData) {
        try {
            logger.info("任务【{}】,开始解析信用卡的可用额度信息", context.get(LUA_TASK_KEY));
            var json = context.get("ccb_credit_limit_html");
            var userInfo = context.get("jsonUserInfo");
            if (json.contains("0130Z1108007")) {
                logger.info("任务【{}】,卡信息获取失败,停止抓取", context.get(LUA_TASK_KEY));
                return;
            }

            var balanceJson = JSON.parseObject(json);
            //index 0代表人民币额度;index 1代表对应的美元额度
            if (!balanceJson.containsKey("SUCCESS")) {
                return;
            }
            if (balanceJson.get("SUCCESS").toString().equals("true") && balanceJson.containsKey("LIST")) {
                balanceJson = balanceJson.getJSONArray("LIST").getJSONObject(0);
                creditCardAllData.setCreditLimit(stringToBigDecimal(balanceJson.getString("CrCrd_CrLine")));  //可用额度
                creditCardAllData.setBalance(stringToBigDecimal(balanceJson.getString("CrCrd_Avl_Lmt_3")));    //余额
                creditCardAllData.setCashLimit(stringToBigDecimal(balanceJson.getString("CrCrd_CshLmt")));    //现金可提取额度
                creditCardAllData.setNameOnCard(userInfo.getString("NAME"));
            }
            logger.info("任务【{}】,解析信用卡的可用额度信息完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,解析信用卡的可用额度信息异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //抓取已出账单列表信息
    get_credit_card_done_bill_list_html: function () {
        try {
            logger.info("任务【{}】,开始采集信用卡已出账单历史列表信息", context.get(LUA_TASK_KEY));
            var userInfo = context.get("jsonUserInfo");
            var individualUrl = context.get("ccb_individualUrl");
            var billListUrl = "https://ibsbjstar.ccb.com.cn" + individualUrl + "&USERID=%s&BRANCHID=%s&SKEY=%s&TXCODE=XE1140";
            billListUrl = String.format(billListUrl, userInfo.getString("USERID"), userInfo.getString("BRANCHID"), userInfo.getString("SKEY"));
            var billListHtml = ajax_get(billListUrl);
            context.put("ccb_done_bill_list_html", billListHtml);
            storeDataToFile(context, billListHtml, "credit_donebill_list.html")
            logger.info("任务【{}】,采集信用卡已出账单历史列表信息完毕", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,采集异常账单历史列表异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //解析已出账单列表信息
    parse_credit_card_done_bill_list_html: function () {
        try {
            logger.info("任务【{}】，开始解析已出账单列表信息，获取历史账单下载的参数", context.get(LUA_TASK_KEY));
            var billListHtml = context.get("ccb_done_bill_list_html");
            context.put("ccb_done_bill_param", null);
            context.put("ccb_done_bill_size", 0);
            //判断页面中是否有历史账单列表
            if (!billListHtml.contains("历史账单列表")) {
                if (billListHtml.contains("XDBA02811022") || billListHtml.contains("YDCA02811101")) {
                    logger.info("任务【{}】，历史账单列表失败:没有可以查询的数据!", context.get(LUA_TASK_KEY));
                } else {
                    logger.error("任务【{}】，历史账单列表失败,停止抓取", context.get(LUA_TASK_KEY));
                    return;
                }
            } else {
                var doc = Jsoup.parse(billListHtml);
                var trs = doc.select("#result > tbody >tr");
                //解析获取id为result的table中的tr，历史记录月份信息从第三个tr开始，头两行为标题
                if (trs.size() < 2) {
                    logger.info("任务【{}】，该用户无历史消费记录，停止抓取", context.get(LUA_TASK_KEY));
                    return;
                }
                var individualUrl = context.get("ccb_individualUrl");
                var param = new LinkedHashMap();
                param.put("yzacc", "");
                param.put("yzflag", "1");
                param.put("yztxcode", "");
                param.put("flagnext", "1");
                param.put("SMSCODE_FRTCTRL", "");
                param.put("SKEY", doc.select("[name = SKEY]").val());
                param.put("USERID", doc.select("[name = USERID]").val());
                param.put("BRANCHID", doc.select("[name = BRANCHID]").val());
                param.put("TXCODE", "XE1144");
                param.put("CrCrd_Acg_Setl_Dt", "");
                param.put("StDt", doc.select("[name = StDt]").val());
                param.put("Prd_Num", doc.select("[name = Prd_Num]").val());
                param.put("clientFileName", "");
                param.put("type", "1");
                //点击下载12个月的已出账单 建设官网只提供12个月的账单下载
                var billUrl = "https://ibsbjstar.ccb.com.cn" + individualUrl;
                context.put("ccb_done_bill_url", billUrl);
                context.put("ccb_done_bill_param", param);
                context.put("ccb_done_bill_size", trs.size());
                context.put("ccb_done_bill_trs", trs);
                context.put("ccb_bldate", "");
            }
            logger.info("任务【{}】，解析已出账单列表信息完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,解析异常账单历史列表异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }

    },

    //采集已出账单页面

    get_credit_done_bill_html: function (index) {
        try {
            logger.info("任务【{}】,开始采集已出账单信息【{}】", context.get(LUA_TASK_KEY), index);
            var billUrl = context.get("ccb_done_bill_url");
            var param = context.get("ccb_done_bill_param");
            var trs = context.get("ccb_done_bill_trs");

            var tds = trs.get(index).select("td");
            var billDateP = tds.get(0).text().trim();
            var BlDate = context.get("ccb_bldate");
            if ("".equals(BlDate)) {
                //抓取账单日
                BlDate = billDateP;
                context.put("ccb_bldate", BlDate);
                logger.info("任务【{}】，输出BlDate的值{}", context.get(LUA_TASK_KEY), BlDate);
            }
            var data = billDateP.replaceAll("-", "");
            param.put("CrCrd_Acg_Setl_Dt", data);
            logger.info("任务【{}】，输出建设时间data{}", context.get(LUA_TASK_KEY), data);
            //param.put("clientFileName", formatNumber(date) + ".txt");
            param.put("clientFileName", "信用卡对账单.txt");
            var billTxt = ajax_post(billUrl, param);
            storeDataToFile(context, billTxt, "信用卡第" + index + "个已出账单消费明细.txt")
            context.put("ccb_done_bill_txt", billTxt);

            logger.info("任务【{}】,采集已出账单信息完成【{}】", context.get(LUA_TASK_KEY), index);
        } catch (e) {
            logger.error("任务【{}】,采集已出账单信息异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //解析账单页面
    parse_credit_done_bill_html: function (billNum, billAllData) {
        try {
            var billTxt = context.get("ccb_done_bill_txt");
            logger.info("任务【{}】，建设银行开始解析前十二个月的账单，第【{}】个账单", context.get(LUA_TASK_KEY), billNum);
            if (StringUtils.isBlank(billTxt)) {
                logger.info("任务【{}】，建设银行开始解析前十二个月的账单，第【{}】个账单,采集失败", context.get(LUA_TASK_KEY), billNum);
                return;
            }
            var mingxis = billTxt.split(/\r\n/g);
            var newStringList = new LinkedList();
            for each(var mingxi in mingxis)
            {
                if (mingxi.trim().length() !== 0) {
                    newStringList.add(mingxi.trim().replaceAll(" {2,}", " "));
                }
            }
            var pay_due_date = "";
            for (var index = 0; index < newStringList.size(); index++) {
                var eachString = newStringList.get(index);
                if (eachString.startsWith("本期账单日")) {
                    var billDate = eachString.split("\)")[1];
                    var billMonth = billDate;
                    billAllData.setBillDate(js_commfuns.formatDate(billDate));                                 //账单月份
                    billAllData.setBillMonth(js_commfuns.formatMonth(billMonth));                               //账单日
                } else if (eachString.startsWith("本期到期还款日")) {
                    if (eachString.contains("已逾期")) {
                        if (StringUtils.isNotBlank(pay_due_date)) {
                            var paymentdate = billMonth + "-" + pay_due_date;
                            billAllData.setPaymentDueDate(js_commfuns.formatDate(paymentdate.replaceAll("-", "")));
                        } else {
                            var paymentdate = billMonth + "-22"
                            billAllData.setPaymentDueDate(js_commfuns.formatDate(paymentdate.replaceAll("-", "")));
                        }

                    } else {
                        var repaymentDate = eachString.split("\)")[1];
                        billAllData.setPaymentDueDate(js_commfuns.formatDate(repaymentDate));//账单月份
                        //截取还款日
                        pay_due_date = repaymentDate.substring(repaymentDate.length - 2, repaymentDate.length);
                    }
                } else if (eachString.startsWith("授信额度")) {
                    var creditLimit = eachString.split("\)")[1];
                    billAllData.setCreditLimit(stringToBigDecimal(creditLimit));
                } else if (eachString.startsWith("取现额度")) {
                    var cashLimit = eachString.split("\)")[1];
                    billAllData.setCashLimit(stringToBigDecimal(cashLimit));
                } else if (eachString.startsWith("本期全部应还款额")) {
                    var tempString = "";
                    var tempIndex = index;
                    while (!tempString.startsWith("本期最低还款额")) {
                        if (tempString.startsWith("人民币")) {
                            var newBalance = tempString.split(" ")[1];
                            billAllData.setNewBalance(stringToBigDecimal(newBalance));
                        } else if (tempString.startsWith("美 元")) {
                            var usdNewBalance = tempString.split(" ")[2];
                            billAllData.setUsdNewBalance(stringToBigDecimal(usdNewBalance));
                        }
                        tempString = newStringList.get(++tempIndex);
                    }
                } else if (eachString.startsWith("本期最低还款额")) {
                    var tempString = "";
                    var tempIndex = index;
                    while (!tempString.startsWith("应还款明细")) {
                        if (tempString.startsWith("人民币")) {
                            var minRepayment = tempString.split("\)")[1];
                            billAllData.setMinPayment(stringToBigDecimal(minRepayment));
                        } else if (tempString.startsWith("美 元")) {
                            var usdMinRepayment = tempString.split("\)")[1];
                            billAllData.setUsdMinPayment(stringToBigDecimal(usdMinRepayment));
                        }
                        tempString = newStringList.get(++tempIndex);
                    }
                } else if (eachString.contains("人民币账户") && eachString.contains("上期账单日余额")) {
                    var lastBalance = eachString.split("\)")[2];
                    billAllData.setLastBalance(stringToBigDecimal(lastBalance));             //上期余额
                } else if (eachString.contains("美元账户") && eachString.contains("上期账单日余额")) {
                    var usdNewBalance = eachString.split("\)")[2];
                    billAllData.setUsdLastBalance(stringToBigDecimal(usdNewBalance));
                } else if (eachString.startsWith("交易明细")) {
                    credit_commfuns.parse_done_bill_expense_for_txt(newStringList.indexOf(eachString), newStringList, billAllData);
                    logger.info("任务【{}】，建设银行开始解析前十二个月的账单，第【{}】个账单详情成功", context.get(LUA_TASK_KEY), index);
                }
            }
            if (parseInt(billNum) == 1) {
                context.put("billDate", billAllData.getBillDate());
                context.put("payDueDate", billAllData.getPaymentDueDate());
            }
            logger.info("任务【{}】，建设银行解析前十二个月的账单，第【{}】个账单完成", context.get(LUA_TASK_KEY), billNum);
        } catch (e) {
            logger.error("任务【{}】,建设银行解析前十二个月的账单，第【{}】个账单异常：", context.get(LUA_TASK_KEY), billNum, e);
            statCaughtExceptionByJS(context, e);
        }
    },

    parse_done_bill_expense_for_txt: function (index, stringList, billAllData) {
        try {
            logger.info("任务【{}】，开始解析具体的消费明细【{}】", context.get(LUA_TASK_KEY), stringList);
            var expenseList = new LinkedList();
            var order_index = 0;
            for (var i = index + 3; i < stringList.size(); i++) {
                var data = stringList.get(i).split(" ");
                if (data.length >= 6) {
                    // 交易日期
                    var tranDate = data[0].trim();
                    // 记账日期
                    var recordDate = data[1].trim();
                    if (StringUtils.isBlank(tranDate) && StringUtils.isBlank(recordDate)) {
                        return;
                    }
                    //判读是否是消费明细 有的卡最后一行是美元账户上期余额
                    if (!tranDate.matches("^[1-9]\\d*$") && !recordDate.matches("^[1-9]\\d*$")) {
                        return;
                    }
                    // 卡号后四位
                    var cardNo = data[2].replaceAll("/扫码", "");
                    // 交易币种
                    var transCurrency = data[3].split("/")[0];// 无script标签
                    if (equals("", transCurrency)) {
                        transCurrency = "OTHER";
                    }
                    // 交易金额
                    var transAmount = data[3].split("/")[1];
                    // 交易说明
                    var transRemark = "";
                    if (data.length > 6) {
                        var buffer = new StringBuffer();
                        for (var j = 5; j < data.length; j++) {
                            buffer.append(data[j]);
                        }
                        transRemark = buffer.toString();
                    } else {
                        transRemark = data[5];
                    }
                    tranDate = js_commfuns.formatDate(tranDate);
                    recordDate = js_commfuns.formatDate(recordDate);
                    transAmount = js_commfuns.formatNumber(transAmount);
                    var expense = js_commfuns.getExpense();                                                //shopping_sheets类账单的明细
                    expense.setId(UUID.randomUUID().toString());                                    //页面没有
                    expense.setCardNum(cardNo);                                                    //卡号后四位
                    expense.setTransDate(tranDate);                                  //格式化交易日期
                    expense.setPostDate(recordDate);                                               //记账日期
                    expense.setDescription(transRemark);                                            //交易说明
                    expense.setAmountMoney(stringToBigDecimal(transAmount));      //交易金额
                    expense.setCurrencyType(transCurrency);                                        //交易币种
                    expense.setCategory(classify(transRemark,expense.getAmountMoney()));    //判断消费类型
                    expense.setOrderIndex(++order_index);                                          //消费详情序号
                    expenseList.add(expense);
                    billAllData.setShoppingSheets(expenseList);
                }
            }
            logger.info("任务【{}】，解析具体的消费明细【{}】完成", context.get(LUA_TASK_KEY), stringList);
        } catch (e) {
            logger.error("任务【{}】，解析具体的消费明细【{}】异常【{}】", context.get(LUA_TASK_KEY), stringList, e);
            statCaughtExceptionByJS(context, e);
        }

    },

    get_credit_done_bill_after12_html: function (index) {
        try {
            logger.info("任务【{}】，信用卡开始获取第【{}】个账单明细", context.get(LUA_TASK_KEY), index);
            var data = new LinkedHashMap();
            var userInfo = context.get("jsonUserInfo");
            data.put("SKEY", userInfo.getString("SKEY"));
            data.put("USERID", userInfo.getString("USERID"));
            data.put("BRANCHID", userInfo.getString("BRANCHID"));
            data.put("TXCODE", "XE1142");
            data.put("clientFileName", "");
            data.put("Prd_Num", Integer.parseInt(index));
            var billUrl = context.get("ccb_done_bill_url");
            var trs = context.get("ccb_done_bill_trs");

            credit_commfuns.setPostData(data, trs.get(index));
            var billInfoHtml = ajax_post(billUrl, data);
            storeDataToFile(context, billInfoHtml, "信用卡第" + index + "个已出账单消费明细.html")
            context.put("ccb_credit_card_done_bill", billInfoHtml);
            logger.info("任务【{}】，信用卡获取第【{}】个账单明细完成", context.get(LUA_TASK_KEY), index);
        } catch (e) {
            logger.error("任务【{}】,信用卡获取第【{}】个账单明细异常：{}", context.get(LUA_TASK_KEY), index, e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //解析12个月之后的账单明细
    parse_credit_done_bill_after12_html: function (index, billAllData) {
        try {
            logger.info("任务【{}】，信用卡开始解析12个月之后的账单页面，第【{}】个账单", context.get(LUA_TASK_KEY), index);
            var billInfoHtml = context.get("ccb_credit_card_done_bill");
            var doc = Jsoup.parse(billInfoHtml);
            var trs = doc.select("#result2").select("tr");
            var billDate = doc.select("#result1 > tbody > tr > td > span:nth-child(2)").select("script").html();
            var repaymentDate = doc.select("#result1 > tbody > tr > td > span:nth-child(3)").select("script").html();
            if (trs.size() > 1) {
                billAllData.setBillDate(js_commfuns.formatDate(billDate));
                if(index == 13){
                    billDate_comm = js_commfuns.formatDate(billDate);
                }
                //账单月份
                billAllData.setBillMonth(js_commfuns.formatMonth(billDate));
                billAllData.setPaymentDueDate(js_commfuns.formatDate(repaymentDate));
                for (var i = 1; i < trs.size(); i++) {
                    var tds = trs.get(i).select("td");
                    if (tds.get(0).text().contains("人民币")) {
                        billAllData.setCreditLimit(stringToBigDecimal(credit_commfuns.getStringDecimal(3, tds)));
                        billAllData.setCashLimit(stringToBigDecimal(credit_commfuns.getStringDecimal(4, tds)));
                        billAllData.setNewBalance(stringToBigDecimal(credit_commfuns.getStringDecimal(1, tds)));
                        billAllData.setLastBalance(stringToBigDecimal(credit_commfuns.getStringDecimal(7, tds)));
                        billAllData.setMinPayment(stringToBigDecimal(credit_commfuns.getStringDecimal(2, tds)));
                    } else if (tds.get(0).text().contains("美元")) {
                        billAllData.setUsdCreditLimit(stringToBigDecimal(credit_commfuns.getStringDecimal(3, tds)));
                        billAllData.setUsdCashLimit(stringToBigDecimal(credit_commfuns.getStringDecimal(4, tds)));
                        billAllData.setUsdNewBalance(stringToBigDecimal(credit_commfuns.getStringDecimal(1, tds)));
                        billAllData.setUsdLastBalance(stringToBigDecimal(credit_commfuns.getStringDecimal(7, tds)));
                        billAllData.setUsdMinPayment(stringToBigDecimal(credit_commfuns.getStringDecimal(2, tds)));
                    }
                }
            }

            logger.info("任务【{}】，信用卡解析12个月之后的账单页面，第【{}】个账单完成", context.get(LUA_TASK_KEY), index);
        } catch (e) {
            logger.error("任务【{}】,信用卡解析12个月之后的账单页面，第【{}】个账单明细异常：{}", context.get(LUA_TASK_KEY), index, e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //抓取近12个月之前的账单
    get_credit_after12_done_bill_txt: function () {
        try {
            logger.info("任务【{}】，开始抓取12个月之前的账单明细", context.get(LUA_TASK_KEY));
            var billUrl = context.get("ccb_done_bill_url");
            var userInfo = context.get("jsonUserInfo");
            var BlDate = context.get("ccb_bldate");
            logger.info("输出时间" + BlDate);
            //抓取近12个月之前所有明细
            var params = new LinkedHashMap();
            params.put("SKEY", userInfo.getString("SKEY"));
            params.put("USERID", userInfo.getString("USERID"));
            params.put("BRANCHID", userInfo.getString("BRANCHID"));
            params.put("TXCODE", "XE1146");
            params.put("CrCrd_CardNo", "all");
            params.put("Seq_Mod_CgyCd", "01");
            params.put("PAGE_JUMP", "1");
            params.put("Seq_MtdCd", "1");
            params.put("Svc_ID", "0");
            var startDate = credit_commfuns.getStartDate(BlDate);
            var endDate = credit_commfuns.getEndDate(BlDate);
            params.put("START_DATE", startDate);
            params.put("END_DATE", endDate);
            params.put("clientFileName", "");
            params.put("STS_TRACE_ID", "");
            params.put("Flt_Acc_SN", "");
            params.put("Flt_Inf_TnCcy_Cd", "");
            params.put("Flt_Txn_Tp_Nm", "");
            params.put("Flt_Prty_Nm_Adr", "");
            params.put("Flt_Txn_Nm_Dsc", "");
            var billForTxt = ajax_post(billUrl, params);
            storeDataToFile(context, billForTxt, "doneBillBefore.txt")
            context.put("ccb_12_bill_txt", billForTxt);
            logger.info("任务【{}】，抓取12个月之前的账单明细完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,抓取12个月之前的账单异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //解析12个月之前的账单明细
    parse_done_bill_txt_after12: function (creditCardAllData) {
        try {
            var billForTxt = context.get("ccb_12_bill_txt");
            logger.info("任务【 {} 】 billForTxt {}", context.get(LUA_TASK_KEY), billForTxt)
            var strings = billForTxt.split(/\r\n/g);
            var newStringList = new LinkedList();
            var order_index = 0;
            var index = 12;
            var billAllData = creditCardAllData.getBills().get(index);
            for each(var sss in strings)
            {
                if (sss.trim().length() !== 0) {
                    newStringList.add(sss.trim().replaceAll(" {2,}", " "));
                }
            }
            var date = null;
            var f_bill_date = creditCardAllData.getBills().get(index).getBillDate()
            if(f_bill_date == null){
                date = billDate_comm;
            }else{
                date = credit_commfuns.getNextBillDate(f_bill_date);
            }

            for each(var string in newStringList)
            {
                if (!string.split(" ")[0].match("\\d{8}")) {
                    continue;
                }
                var expense = js_commfuns.getExpense();
                //交易日期
                var transDate = string.split(" ")[0] === undefined ? "" : string.split(" ")[0]
                logger.info("任务【 {} 】 transDate {}", context.get(LUA_TASK_KEY), transDate)
                //记账日期
                var postDate = string.split(" ")[1] === undefined ? "" : string.split(" ")[1]
                logger.info("任务【 {} 】 postDate {}", context.get(LUA_TASK_KEY), postDate)
                //卡号
                var cardFullNo = string.split(" ")[2] === undefined ? "" : string.split(" ")[2]

                logger.info("任务【 {} 】 cardFullNo {}", context.get(LUA_TASK_KEY), cardFullNo)
                //交易币种
                var currencyType = string.split(" ")[4] === undefined ? "" : string.split(" ")[4]
                logger.info("任务【 {} 】 currencyType {}", context.get(LUA_TASK_KEY), currencyType)
                //交易金额 负的代表收入 正的代表支出
                var amountMoney = string.split(" ")[5] === undefined ? "" : string.split(" ")[5]
                logger.info("任务【 {} 】 amountMoney {}", context.get(LUA_TASK_KEY), amountMoney)
                //消费类型
                var remark = string.split(" ")[3] === undefined ? "" : string.split(" ")[3]
                logger.info("任务【 {} 】 remark {}", context.get(LUA_TASK_KEY), remark)
                //交易描述
                var description = "";
                for (var i = 6; i < string.split(" ").length; i++) {
                    if ("".equals(description)) {
                        description = string.split(" ")[i];
                    } else {
                        description = description + " " + (string.split(" ")[i] === undefined ? "" : string.split(" ")[i]);
                    }
                }
                expense.setId(UUID.randomUUID().toString());
                cardFullNo = js_commfuns.formatNumber(cardFullNo);
                expense.setTransDate(js_commfuns.formatDate(transDate));
                expense.setPostDate(js_commfuns.formatDate(postDate));
                expense.setCardNum(cardFullNo.substring(cardFullNo.length() - 4, cardFullNo.length()));
                expense.setDescription(description);
                expense.setCurrencyType(convertCurr(currencyType));
                var amount = js_commfuns.formatNumber(amountMoney);
                expense.setAmountMoney(stringToBigDecimal(amount));
                expense.setCategory(classify(description,expense.getAmountMoney()));
                expense.setRemark(remark);
                //判断交易日和账单日的的大小，如果到一个新的月份，则order_index置为0，获取已经抓取到的下一个月份的billAllData
                if (index + 1 < creditCardAllData.getBills().size() && expense.getPostDate().compareTo(date) <= 0) {
                    order_index = 0;
                    //当当前expense明细的日期
                    do {
                        billAllData = creditCardAllData.getBills().get(++index);
                        //获取下一个账单日
                        date = credit_commfuns.getNextBillDate(date);
                    } while (expense.getPostDate().compareTo(date) < 0);
                }
                expense.setOrderIndex(++order_index);
                billAllData.getShoppingSheets().add(expense);
            }

            //前12个月已做过分期和处理本期新增处理，此处只处理12个月之前的
            for (var i = 12; i < creditCardAllData.getBills().size(); i++) {
                credit_commfuns.parse_credit_card_installments(creditCardAllData.getBills().get(i));
                credit_commfuns.compute_bill_charges(creditCardAllData.getBills().get(i));
            }
            logger.info("任务【{}】，解析12个月之前的账单完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,抓取12个月之前的账单异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    handle_card_baseinfo: function (creditCardAllData) {
        try {
            var cardList = context.get("ccb_credit_cardlist");
            var fullCardNo = new StringBuilder();
            var fourCardNo = new StringBuilder();
            for (var i = 0; i < cardList.size(); i++) {
                var map = cardList.get(i);
                if ("".equals(fullCardNo.toString())) {
                    fullCardNo.append(map.get("card_no"));
                    fourCardNo.append(map.get("card_num_4"));
                } else {
                    fullCardNo.append("," + map.get("card_no"));
                    fourCardNo.append("," + map.get("card_num_4"));
                }
                creditCardAllData.setOpenBank(map.get("card_bank"));
            }
            creditCardAllData.setFullCardNum(fullCardNo.toString());
            creditCardAllData.setCardNum(fourCardNo.toString());
        } catch (e) {
            logger.error("任务【{}】,处理建设卡号问题异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }

    },

    //采集未出账单页面
    get_credit_undone_bill_txt: function () {
        try {
            logger.info("任务【{}】，开始采集信用卡未出账单明细", context.get(LUA_TASK_KEY));

            var userInfo = context.get("jsonUserInfo");
            var individualUrl = context.get("ccb_individualUrl");
            var undoneBillUrl = "https://ibsbjstar.ccb.com.cn" + individualUrl;
            var TXCODE = "XE1146";// 消费记录查询
            var Svc_ID = "1";// 未出账单
            var map = new LinkedHashMap();
            map.put("Svc_ID", Svc_ID);
            map.put("TXCODE", TXCODE);
            map.put("SKEY", userInfo.getString("SKEY"));
            map.put("USERID", userInfo.getString("USERID"));
            map.put("BRANCHID", userInfo.getString("BRANCHID"));
            map.put("CrCrd_CardNo", "all");
            map.put("PAGE_JUMP", "1");
            map.put("Seq_Mod_CgyCd", "01");
            map.put("Seq_MtdCd", "1");
            //发送post请求获取未出账单的TXT
            var unbillHtml = ajax_post(undoneBillUrl, map);
            storeDataToFile(context, unbillHtml, "credit_unbill.txt")
            context.put("ccb_undone_bill_html", unbillHtml);
            logger.info("任务【{}】，采集信用卡未出账单明细完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,采集信用卡未出账单明细异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    parse_credit_undone_bill_txt: function (creditCardAllData) {
        try {
            logger.info("任务【{}】，开始解析未出账单页面", context.get(LUA_TASK_KEY));
            //获取一个未出账单的对象
            var billAllData = getUNDoneBillAllDataHeaderData(creditCardAllData);
            billAllData.setCreditLimit(creditCardAllData.getCreditLimit());
            billAllData.setCashLimit(creditCardAllData.getCashLimit());
            billAllData.setBillMonth(yyyy_MM_PARSER.format(new Date()));

            //如果没有交易明细，继续抓取，如果包含代码"0130Z1109001"或"0130Z1108007"表示会话超时暂处理为抛出异常
            var unbillHtml = context.get("ccb_undone_bill_html");
            if (unbillHtml.contains("无交易明细记录！")) {
                logger.info("任务【{}】，无交易明细记录！", context.get(LUA_TASK_KEY));
            } else if (unbillHtml.contains("0130Z1109001") || unbillHtml.contains("0130Z1108007")) {
                logger.info("任务【{}】，未出账单抓取会话超时", context.get(LUA_TASK_KEY));
                throw new BankException(BankConstants.BACR_99602_20, "会话超时，请重新登录");
            } else {
                //解析为出账单的TXT信息
                credit_commfuns.parseUndoneBillForTxt(unbillHtml, billAllData);
                //解析分期信息
                credit_commfuns.parse_credit_card_installments(billAllData);
                //计算未出账单的账单金额----本期应还
                credit_commfuns.computeUnBillBalance(billAllData);
                //计算账单中的新增金额----本期新增
                credit_commfuns.compute_bill_charges(billAllData);

                logger.info("CCB taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 采集完毕未出账单信息");
            }
            //由于页面上没有抓取到未出账单的账单日，但是有已出账单的账单日，所以做未出账单日计算
            credit_commfuns.computeUnbillDate(billAllData);
            logger.info("CCB taskKey=" + context.get(Constants.LUA_TASK_KEY) + " computeUnbillDate计算卡未出账单的账单日月");
            //处理上期账单金额
            //处理未出账单的lastpayment
            var shopping_sheets = billAllData.getShoppingSheets();
            var last_payment = new BigDecimal(0.00);
            for(var i=0;i<shopping_sheets.size();i++){
                var expnese = shopping_sheets.get(i);
                if(expnese.getAmountMoney()!=null && expnese.getAmountMoney()<0){
                    last_payment = last_payment.add(expnese.getAmountMoney())
                }
            }
            billAllData.setLastPayment(last_payment);
            credit_commfuns.computeUnBillLastBalance(creditCardAllData);
            logger.info("任务【{}】，解析未出账单页面完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,解析未出账单页面异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //解析未出账单的明细
    parseUndoneBillForTxt: function (unbillHtml, billAllData) {
        try {
            var strings = unbillHtml.split(/\r\n/g);
            var newStringList = new LinkedList();
            var order_index = 0;
            for each(var mingxi in strings)
            {
                if (mingxi.trim().length() !== 0) {
                    newStringList.add(mingxi.trim().replaceAll(" {2,}", " "));
                }

            }
            var expenseList = new ArrayList();
            for each(var string in newStringList)
            {
                if (!string.split(" ")[0].match("\\d{8}")) {
                    continue;
                }
                var expense = js_commfuns.getExpense();
                expense.setId(UUID.randomUUID().toString());
                //交易日期
                var transDate = string.split(" ")[0] !== undefined ? string.split(" ")[0] : ""
                //记账日期
                var postDate = string.split(" ")[1] !== undefined ? string.split(" ")[1] : ""
                //卡号
                var cardFullNo = string.split(" ")[2] !== undefined ? string.split(" ")[2] : ""
                //交易币种
                var currencyType = string.split(" ")[4] !== undefined ? string.split(" ")[4] : ""
                //交易金额 负的代表收入 正的代表支出
                var amountMoney = string.split(" ")[5] !== undefined ? string.split(" ")[5] : ""
                if ("元".equals(amountMoney)) {
                    amountMoney = string.split(" ")[6] !== undefined ? string.split(" ")[6] : ""
                }
                //消费类型
                var remark = string.split(" ")[3] !== undefined ? string.split(" ")[3] : ""
                //交易描述
                var description = "";
                for (var i = 6; i < string.split(" ").length; i++) {
                    if ("".equals(description)) {
                        description = string.split(" ")[i] !== undefined ? string.split(" ")[i] : ""
                    } else {
                        description = description + " " + (string.split(" ")[i] !== undefined ? string.split(" ")[i] : "");
                    }
                }
                cardFullNo = js_commfuns.formatNumber(cardFullNo);
                expense.setTransDate(js_commfuns.formatDate(transDate));
                expense.setPostDate(js_commfuns.formatDate(postDate));
                expense.setCardNum(cardFullNo.substring(cardFullNo.length() - 4, cardFullNo.length()));
                expense.setDescription(description);
                expense.setCurrencyType(convertCurr(currencyType));
                var amountMoney = js_commfuns.formatNumber(amountMoney);
                expense.setAmountMoney(stringToBigDecimal(amountMoney));
                expense.setCategory(classify(description,expense.getAmountMoney()));
                expense.setRemark(remark);
                expense.setOrderIndex(++order_index);
                expenseList.add(expense);
            }
            billAllData.setShoppingSheets(expenseList);
        } catch (e) {
            logger.error("任务【{}】,解析未出账单txt页面异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }

    },

    computeUnBillBalance: function (billAllData) {
        var balance = new BigDecimal(0);
        var expenses = billAllData.getShoppingSheets();
        if (expenses.size() == 0) {
            return;
        }
        for (var i = 0; i < expenses.size(); i++) {
            var expense = expenses.get(i);
            //消费明细里面正的代表支出 负的目前是上期还款
            if (expense.getAmountMoney() !== null) {
                balance = balance.add(expense.getAmountMoney().abs());
            }
        }
        billAllData.setNewBalance(balance);
    },

    computeUnbillDate: function (billAllData) {
        var billDate = context.get("billDate");
        var payDueDate = context.get("payDueDate");
        logger.info("CCB taskKey=" + context.get(Constants.LUA_TASK_KEY) + " computeUnbillDate计算卡未出账单的账单日月开始");
        //抓取到非空的billDate和payDueDate则把时间往后推一个月
        if (billDate != null && payDueDate != null) {
            try {
                var calendar = Calendar.getInstance();
                calendar.setTime(billDate);
                calendar.add(Calendar.MONTH, 1);// 把日期往后增加一个月.整数往后推,负数往前移动
                billDate = calendar.getTime(); // 这个时间就是日期往后推一天的结果
                var billMonth = DateFormatUtils.format(billDate, "yyyy-MM");
                var newPaymentDate = null;
                if (payDueDate != null) {
                    calendar.setTime(payDueDate);
                    calendar.add(Calendar.MONTH, 1);
                    newPaymentDate = calendar.getTime();
                }
                billAllData.setBillDate(billDate);
                billAllData.setBillMonth(billMonth);
                billAllData.setPaymentDueDate(newPaymentDate);
            } catch (e) {
                statCaughtExceptionByJS(context, e);
                logger.error("ccb taskKey=" + context.get(Constants.LUA_TASK_KEY) + "解析日期格式出错" + billDate, e);
            }
        } else {
            var date = new Date();
            var calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.MONTH, 1);// 把日期往后增加一个月.整数往后推,负数往前移动
            date = calendar.getTime(); // 这个时间就是日期往后推一天的结果
            var billMonth = DateFormatUtils.format(date, "yyyy-MM");
            billAllData.setBillMonth(billMonth);
            billAllData.setPaymentDueDate(date);
        }
    },

    computeUnBillLastBalance: function (cardAllData) {
        var last_balance = BigDecimal.ZERO;
        if (cardAllData.getBills() !== null && cardAllData.getBills().size() > 1 && cardAllData.getBills().get(1) !== null) {
            last_balance = cardAllData.getBills().get(0).getNewBalance();
            cardAllData.getBills().get(cardAllData.getBills().size() - 1).setLastBalance(last_balance);

            var expenses = cardAllData.getBills().get(cardAllData.getBills().size() - 1).getShoppingSheets();
            for each(var expense in expenses)
            {
                last_balance = last_balance.add(expense.getAmountMoney());
            }
        }
        cardAllData.getBills().get(cardAllData.getBills().size() - 1).setNewBalance(stringToBigDecimal(last_balance.toString()));
    },

    getNextBillDate: function (date) {
        /*var sdf = new SimpleDateFormat("yyyy-MM-dd");
         var billDate = sdf.parse(date);*/
        var cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, -1);
        date = cal.getTime();
        return date;
    },

    //解析分期明细
    parse_credit_card_installments: function (billAllData) {
        var expenseList = billAllData.getShoppingSheets();
        var installmentList = null;
        if (billAllData.getInstallments() == null) {
            installmentList = new ArrayList();
        } else {
            installmentList = billAllData.getInstallments();
        }
        //分期手续费
        var handExpenseList = new LinkedList();
        //分期金额
        var needHandExpenseList = new LinkedList();
        for (var i = 0; i < expenseList.size(); i++) {
            var expense = expenseList.get(i);
            var description = expense.getDescription();
            //判断是否是分期账单
            if (description.contains("转分期付款") || description.contains("分期乐")) {
                continue;
            } else if (description.replace(/\s+/g, "").contains("*金额") || description.replace(/\s+/g, "").contains("分期*") || description.replace(/\s+/g, "").contains("现金分期*") || description.replace(/\s+/g, "").contains("账单分期*")) {
                continue;
            } else if (description.contains("返现")) {
                continue;
            } else if ((description.contains("分期") && description.contains("手续费")) || (description.contains("等额还款") && description.contains("手续费"))) {
                handExpenseList.add(expense);
                continue;
            } else if ((description.contains("分期") && !description.contains("手续费")) || (description.contains("等额还款") && !description.contains("手续费"))) {
                needHandExpenseList.add(expense);
                continue;
            }
        }
        try {
            if (handExpenseList.size() == 0) {
                logger.info("ccb taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 解析" + billAllData.getBillMonth() + "的账单无手续费分期情况");
            }
            if (needHandExpenseList.size() == 0) {
                logger.info("ccb taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 解析" + billAllData.getBillMonth() + "的账单无分期情况");
            }
        } catch (e) {
            // statCaughtExceptionByJS(context, e);
            logger.error("ccb taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 解析" + billAllData.getBillMonth() + "的分期,List排序出错", e);
        }
        if (handExpenseList.size() > needHandExpenseList.size()) {
            logger.info("ccb taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 解析" + billAllData.getBillMonth() + "的分期,分期手续费List长度大于具体分期情况List,不符合正常情况");
        }
        if (needHandExpenseList.size() > 0) {
            for (var index = 0; index < needHandExpenseList.size(); index++) {
                var expense = needHandExpenseList.get(index);
                var description = expense.getDescription();
                try {
                    var installment = js_commfuns.getInstallment();
                    installment.setPostDate(expense.getPostDate());
                    installment.setTransDate(expense.getTransDate());
                    installment.setInstallmentDesc(description);
                    if (description.contains("/")) {
                        //从描述中取到总期数
                        installment.setTotalMonth(Integer.parseInt(description.substring(description.indexOf("/") + 1, description.length())));
                        if (description.contains("分期") && description.contains(":借记卡")) {
                            //从描述中获取到当前期数
                            installment.setCurrentMonth(Integer.parseInt(description.substring(description.indexOf(":借记卡") + 9, description.indexOf("/"))));
                        } else if (description.contains("分期") && description.contains("账单 ")) {
                            installment.setCurrentMonth(Integer.parseInt(description.substring(description.indexOf("账单 ") + 3, description.indexOf("/"))));
                        } else if (description.contains("等额还款") && description.contains("账单")) {
                            var tempDesc = description.replace(/\s+/g, "")
                            installment.setCurrentMonth(Integer.parseInt(tempDesc.substring(tempDesc.indexOf("账单") + 2, tempDesc.indexOf("/"))));
                        } else {
                            //等额还款单期金额170314账单01/12
                            //从描述中获取到当前期数
                            installment.setCurrentMonth(Integer.parseInt(description.substring(description.indexOf(":分期") + 3, description.indexOf("/"))));
                        }
                    }
                    installment.setCurrencyType(expense.getCurrencyType());
                    installment.setAmountMoney(expense.getAmountMoney());
                    if (description.contains("现金")) {
                        installment.setInstallmentType("CASH");
                    } else {
                        installment.setInstallmentType("BILL");
                    }
                    if (index < handExpenseList.size()) {
                        var handExpense = handExpenseList.get(index);
                        var newDescription = handExpense.getDescription();
                        if (newDescription.contains("手续费")) {
                            //设置手续费信息
                            installment.setHandingFee(handExpense.getAmountMoney());
                            installment.setHandingfeeDesc(newDescription);
                        }
                    }
                    installment.setBillId(billAllData.getBillId());
                    installment.setShoppingsheetId(expense.getId());
                    installmentList.add(installment);
                    billAllData.setShoppingSheets(expenseList);
                    billAllData.setInstallments(installmentList);
                } catch (e) {
                    statCaughtExceptionByJS(context, e);
                    logger.error("ccb taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 匹配卡" + billAllData.getBillMonth() + "的分期出错", e);
                }
            }
        }
    },

    //计算金额
    compute_bill_charges: function (billAllData) {
        var charges = new BigDecimal(0);
        var lastPayment = new BigDecimal(0);
        var expenses = billAllData.getShoppingSheets();
        if (expenses.size() == 0) {
            return;
        }
        for (var i = 0; i < expenses.size(); i++) {
            var expense = expenses.get(i);
            //消费明细里面正的代表支出 负的目前是上期还款
            if (expense.getAmountMoney() !== null) {
                if (expense.getAmountMoney().compareTo(new BigDecimal(0)) == 1) {
                    charges = charges.add(expense.getAmountMoney().abs());
                } else {
                    lastPayment = lastPayment.add(expense.getAmountMoney());
                }
            }
        }
        billAllData.setNewCharges(charges);
    },

    setPostData: function (data, tr) {
        var tds = tr.select("td");
        var BlDay = tds.get(0).text().trim();
        var startDate = credit_commfuns.getPostStartDate(BlDay);
        var endDate = credit_commfuns.getPostEndDate(BlDay);
        data.put("CrCrd_Acg_Setl_Dt", endDate);
        data.put("StDt", startDate);
    },

    getStringDecimal: function (index, tds) {
        return tds.get(index).select("script").html().substring(tds.get(index).select("script").html().indexOf("('") + 2, tds.get(index).select("script").html().indexOf(("')")));
    },

    getStartDate: function (BlDate) {
        var sdf = new SimpleDateFormat("yyyy-MM-dd");
        var sdf1 = new SimpleDateFormat("yyyyMMdd");
        var date = sdf.parse(BlDate);
        var cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, -2);
        cal.add(Calendar.DATE, 1);
        var startDate = sdf1.format(cal.getTime());
        return startDate;
    },

    getEndDate: function (BlDate) {
        var sdf = new SimpleDateFormat("yyyy-MM-dd");
        var sdf1 = new SimpleDateFormat("yyyyMMdd");
        var date = sdf.parse(BlDate);
        var cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, -1);
        var startDate = sdf1.format(cal.getTime());
        return startDate;
    },
    getPostStartDate: function (BlDate) {
        var sdf = new SimpleDateFormat("yyyy-MM-dd");
        var sdf1 = new SimpleDateFormat("yyyyMMdd");
        var date = sdf.parse(BlDate);
        var cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, -1);
        cal.add(Calendar.DATE, 1);
        var startDate = sdf1.format(cal.getTime());
        return startDate;
    },
    getPostEndDate: function (blDay) {
        return blDay.replaceAll("-", "");
    }
}

/**
 * 借记卡解析js方法
 */
var debit_commfuns = {

    //获取借记卡列表
    get_debit_card_list_html: function () {
        try {
            logger.info("任务【{}】，开始请求获取用户储蓄卡列表信息", context.get(LUA_TASK_KEY));
            var userInfo = context.get("jsonUserInfo");
            var individualUrl = context.get("ccb_individualUrl");
            //储蓄卡列表URL拼接
            var cardListUrl = "https://ibsbjstar.ccb.com.cn" + individualUrl + "&TXCODE=310102&USERID=%s&BRANCHID=%s&SKEY=%s&SELECT_TYPE=cxzh";
            cardListUrl = String.format(cardListUrl, userInfo.getString("USERID"), userInfo.getString("BRANCHID"), userInfo.getString("SKEY"));
            //用获取到的页面发送ajax请求
            var depositCardList = ajax_get(cardListUrl);
            //保存到借记卡列表页面中
            storeDataToFile(context, depositCardList, "depositCardList.html")
            context.put("ccb_debit_card_list_html", depositCardList);
            logger.info("任务【{}】，请求获取用户储蓄卡列表完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.info("任务【{}】,请求获取用户储蓄卡列表异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }

    },

    //解析借记卡数量
    parse_debit_card_size: function () {
        try {
            logger.info("任务【{}】,开始解析借记卡数量", context.get(LUA_TASK_KEY));
            var cardListHtml = context.get("ccb_debit_card_list_html")
            var doc = Jsoup.parse(cardListHtml);
            //Jsoup解析Html，通过css选择器获取卡信息所在tr的集合
            var trs = doc.select("tr:not(.trbg):not(.tab_qymey_td):not(:first-child):not([hasblance='0'])");
            context.put(keys.DEBT_CARD_SIZE, trs.size());
            context.put("ccb_debit_baseinfo_trs", trs);
            logger.info("任务【{}】，获取到借记卡数量【{}】", context.get(LUA_TASK_KEY), trs.size());
        } catch (e) {
            logger.info("任务【{}】,解析借记卡数量异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //抓取借记卡基本信息
    get_debit_card_base_info: function (index) {
        try {
            logger.info("任务【{}】，建设银行开始获取借记卡基本卡信息", context.get(LUA_TASK_KEY));
            var trs = context.get("ccb_debit_baseinfo_trs");
            var tds = trs.get(index).select("td");
            var urlInfo = context.get("jsonUrlInfo");
            if (tds.size() >= 10) {
                //拼接获取卡信息的url
                var url = "https://ibsbjstar.ccb.com.cn" + urlInfo.getString("P1ACTION") + "&TXCODE=N31001&SKEY=%s&USERID=%s&BRANCHID=%s&ACC_NO=%s&ACC_TYPE_FLAG=lct&CurTypeDesc=人民币&AccAlias=%s&AgreeType=C&BranchDesc=&SEND_USERID=&NOACCTJ=1";
                //从a标签的onclick时间中取到包含卡号的参数
                var cardNo = tds.get(6).select("a").get(0).attr("onclick");
                //对卡号参数进行格式化处理，参数中已“,”分割，第一个是卡号
                var formatCardNo = js_commfuns.formatNumber(cardNo.split(",")[0]);
                //从第八个td中取到开户行
                var openBank = tds.get(7).text();
                var jsonUserInfo = context.get("jsonUserInfo");
                //格式化url，给url中的参数赋值
                url = String.format(url, jsonUserInfo.get("SKEY"), jsonUserInfo.get("USERID"), jsonUserInfo.get("BRANCHID"), formatCardNo, openBank);
                //发送请求
                var html = ajax_get(url);
                storeDataToFile(context, html, index+"ccb_base_info.html")
                logger.info("任务【{}】,借记卡抓取到基本信息页面", context.get(LUA_TASK_KEY));
                context.put("ccb_base_info_html", html);

            } else {
                logger.error("任务【{}】,借记卡为抓取到基本信息页面为空", context.get(LUA_TASK_KEY));
                context.put("ccb_base_info_html", null);
            }
        } catch (e) {
            logger.info("任务【{}】,借记卡抓取到基本信息页面异常：{}", context.get(LUA_TASK_KEY), e);
            context.put("ccb_base_info_html", null);
            statCaughtExceptionByJS(context, e);
        }
    },

    //解析借记卡基本信息
    parse_debit_card_base_info: function (creditCardAllData) {
        try {
            logger.info("任务【{}】,开始解析借记卡基本信息页面", context.get(LUA_TASK_KEY));
            var html = context.get("ccb_base_info_html");
            if (html != null) {
                //请求后获取开户时间
                var doc1 = Jsoup.parse(html);
                var trs1 = doc1.select("tr");
                //开户时间初始化为""
                var openTime = "";
                //借记卡中可能有多个账户，比如整存整取，活期
                if (trs1.size() > 3) {
                    //循环所有的账户，取到每一个账户的开户时间，取最早的一个作为开卡时间
                    for (var i = 3; i < trs1.size(); i++) {
                        var openTime1 = trs1.get(i).select("td").get(0).text();
                        if (!"".equals(openTime) && openTime.compareTo(openTime1) > 0) {
                            openTime = openTime1;
                        } else if ("".equals(openTime)) {
                            openTime = openTime1;
                        }
                    }
                }
                //做非空判断，不是空字符串则格式化并赋值
                if (!"".equals(openTime)) {
                    creditCardAllData.setOpenTime(js_commfuns.formatDate(openTime));
                }
                var trs = context.get("ccb_debit_baseinfo_trs");
                for (var index = 0; index < trs.size(); index++) {
                    var tds = trs.get(index).select("td");
                    if (tds.size() >= 10) {
                        //从a标签的onclick时间中取到包含卡号的参数
                        var cardNo = tds.get(6).select("a").get(0).attr("onclick");
                        //对卡号参数进行格式化处理，参数中已“,”分割，第一个是卡号
                        var formatCardNo = js_commfuns.formatNumber(cardNo.split(",")[0]);
                        //从第八个td中取到开户行
                        var openBank = tds.get(7).text();
                        //如果获取到的卡号不为空则格式化并赋值
                        if (!StringUtils.isBlank(formatCardNo)) {
                            creditCardAllData.setFullCardNum(formatCardNo);
                            creditCardAllData.setCardNum(formatCardNo.substring(formatCardNo.length() - 4, formatCardNo.length()));
                        }
                        //如果开户行不为空，则赋值
                        creditCardAllData.setOpenBank("");
                        if (!StringUtils.isBlank(openBank)) {
                            creditCardAllData.setOpenBank(openBank);
                        }
                    }
                }
            }
            logger.info("任务【{}】,解析借记卡基本信息页面完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,解析借记卡基本信息页面异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    before_turn_other: function () {
        try {
            logger.info("任务【{}】，借记卡前置跳转开始", context.get(LUA_TASK_KEY));
            //从ThreadLocal中获取用户信息和url信息
            var userInfo = context.get("jsonUserInfo");
            var individualUrl = context.get("ccb_individualUrl");
            //拼接获取跳转到查询借记卡明细的页面的url
            var srcUrl = "https://ibsbjstar.ccb.com.cn" + individualUrl + "&PT_LANGUAGE=CN&PT_STYLE=1&TXCODE=N31010&SKEY=%s&USERID=%s&BRANCHID=%s&SKEY=%s";
            srcUrl = String.format(srcUrl, userInfo.getString("SKEY"), userInfo.getString("USERID"), userInfo.getString("BRANCHID"), userInfo.getString("SKEY"));
            //参数从这个frameHtml中获取
            var frameHtml = ajax_get(srcUrl);
            var framedoc = Jsoup.parse(frameHtml);
            //Jsoup解析页面上为明细字样的span
            var el = framedoc.select("#scrollPic > ul > li > div > div > div.pbd_cxdiv > span[data_id=mingxi]");
            //遍历获取所有卡参数值并拼接成url存在lua的table中
            for (var i = 0; i < el.size(); i++) {
                var val = el.get(i).attr("values");
                //获取到必要参数,并拼接跳转url
                lua_commfuns.getSrcUrl2(Integer.parseInt(i), val);
            }
            logger.info("任务【{}】，借记卡前置跳转完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,借记卡前置跳转异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }

    },

    down_debit_bill_html: function (creditCardAllData, cardNum) {
        try {
            logger.info("任务【{}】,借记卡开始下载账单明细,card【{}】", context.get(LUA_TASK_KEY), cardNum);
            //获取一些基本参数信息
            var cardNo = creditCardAllData.getFullCardNum();
            var cardFourNo = creditCardAllData.getCardNum();
            var individualUrl = context.get("ccb_individualUrl");

            //跳转到每张卡Iframe账单页面并获取页面
            var html = lua_commfuns.goToSrcUrl(Integer.parseInt(cardNum));
            //如果返回html中包含“fail”,则抛异常“登录成功后页面跳转超时”
            if (html.contains("fail")) {
                logger.error("任务【{}】，借记卡【{}】，下载账单明细时naviget访问下载页面超时", context.get(LUA_TASK_KEY), cardNum);
                throw new BankException(BankConstants.BALO_99601_50, "naviget访问下载页面超时");
            }
            //跳转后等待页面渲染
            Thread.sleep(3000);

            //获取明细起止时间
            var map = debit_commfuns.getStartAndEndDate();
            //把起止时间设为查询条件
            lua_commfuns.setCCBQueryCondition(map.get("beginDate"), map.get("endDate"), cardNum);

            //判断有没有账单明细，如果没有则无法下载
            var flag = lua_commfuns.isDownload(cardNum);
            //若flag为“fail”，则无账单明细
            if (flag.equals("fail")) {
                logger.info("CCBBank:taskKey=" + context.get(LUA_TASK_KEY) + " 第" + cardNum + "张储蓄卡无账单明细!!!");
                context.put("ccb_debit_billhtml", "无账单明细");
            }

            var params = new LinkedHashMap();
            //根据起止日期从当前frame中获取下载请求的参数
            var json = lua_commfuns.getPostParams(map.get("beginDate"), map.get("endDate"), cardNum);
            //如果返回fail 则获取下载账单请求所需参数失败，抛异常消费明细获取失败
            if (json.contains("fail")) {
                logger.info("CCBBank:taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 第" + cardNum + "张储蓄卡账单明细下载失败!!!");
                throw new BankException(BankConstants.BACR_20306_30, "下载历史账单明细失败!");
            }
            //获取到参数的json
            var jsonObject = JSON.parseObject(json);
            var entries = jsonObject.entrySet();
            //遍历参数，并赋值到params中
            for each(var entry in entries)
            {
                if (entry.getKey().equals("A_STR")) {
                    var s = entry.getValue().toString().replaceAll(" ", "+");
                    s += "+";
                    params.put("A_STR", s);
                }
                params.put(entry.getKey(), entry.getValue().toString());
            }
            params.put("ACCSIGN", "\n" + "\n" + "\n" + "0101010|0101|人民币|0|0");
            params.put("START_DATE", map.get("beginDate"));
            params.put("END_DATE", map.get("endDate"));
            params.put("ACC_NO", cardNo);
            params.put("shangxian", "");
            params.put("xiaxian", "");
            params.put("select", "");
            params.put("TXCODE", "310206");
            params.put("clientFileName", "交易明细_" + cardFourNo + "_" + map.get("beginDate") + "_" + map.get("endDate") + ".txt");
            params.put("STR_USERID", params.get("USERID"));
            params.put("index", cardNum.toString());
            var billUrl = "https://ibsbjstar.ccb.com.cn" + individualUrl;
            //发送请求获取消费明细
            var billHtml = lua_commfuns.ajax_post_dif_ie(billUrl, params);
            storeDataToFile(context, billHtml, "bill_" + cardNum + ".txt")
            context.put("ccb_debit_billhtml", billHtml);

        } catch (e) {
            logger.error("任务【{}】,借记卡前置跳转异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }

    },

    parse_debit_bill_html: function (creditCardAllData, cardNum, crawlerDate) {
        try {
            var billHtml = context.get("ccb_debit_billhtml");
            if (billHtml.equals("无账单明细")) {
                logger.info("任务【{}】，借记卡第【{}】张卡没有账单明细", context.get(LUA_TASK_KEY), cardNum);
                return;
            }
            logger.info("CCBBank:taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 解析第" + cardNum + "张借记卡的TXT开始");
            //已\n为分隔符号，获得一个billLines数组
            var billLines = billHtml.split("\n");
            var lineList = new LinkedList();
            for each(var billLine in billLines)
            {
                //只保留有明细所在行的信息，去除空格分隔行
                if (billLine.trim().length() !== 0) {
                    lineList.add(billLine.trim());
                }
            }
            var monthListMap = new LinkedHashMap();
            var cardNo = "";
            //循环获取的明细集合，如果某一行为空则跳出本次循环，继续解析
            for each(var line in lineList)
            {
                if (StringUtils.isBlank(line)) {
                    continue;
                }
                //TXT格式为
                /*账　　号：4367422434250337268
                 开户机构：北京市
                 币    种： 人民币
                 记账日,交易日期,交易时间,交易地点,支出,收入,账户余额,对方账号,对方户名,币种,摘要
                 20170410,20170410,18:05:23,短信服务费,2.00,,31.7,10111000*****7309900900049,对私短信服务费暂挂户,人民币,短信服务费 */
                if (line.contains("：")) {
                    var lines = line.split("：");
                    if (lines.length == 2) {
                        var key = lines[0].replaceAll(" |\\u3000", "").trim();
                        var value = lines[1].replaceAll(" |\\u3000", "").trim();
                        if (key.contains("账号") && !key.contains(",")) {
                            cardNo = value;
                            creditCardAllData.setFullCardNum(value);
                        } else if (key.contains("开户机构")) {
                            creditCardAllData.setOpenBank(value);
                        }
                    }
                }
                if (line.contains(",")) {
                    //账单明细实例:记账日,交易日期,交易时间,交易地点,支出,收入,账户余额,对方账号,对方户名,币种,摘要
                    var lines = line.split(",");
                    if (lines.length == 11) {
                        var flag = lines[0];
                        //从明细中可以到交易时间，通过交易时间确定抓到了哪些月份的账单
                        if (flag.matches("^[1-9]\\d*$")) {
                            //建设借记卡可以直接下载所查到的账单
                            //把同一个月份的账单放到已月份为Key的map中
                            if (monthListMap.containsKey(flag.substring(0, 6))) {
                                monthListMap.get(flag.substring(0, 6)).add(line);
                            } else {
                                var tempList = new LinkedList();
                                //把明细放到一个临时list中
                                tempList.add(line);
                                monthListMap.put(flag.substring(0, 6), tempList);
                            }
                        }
                    }
                }
            }
            //卡号后4位
            var cardLastFourNum = "";
            if (cardNo.length() == 19) {
                cardLastFourNum = cardNo.substring(cardNo.length() - 4, cardNo.length());
                creditCardAllData.setFullCardNum(cardNo);
                creditCardAllData.setCardNum(cardLastFourNum);
            }
            logger.info("CCBBank:taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 第" + cardNum + "张借记卡消费明细月份数量" + monthListMap.size());
            //遍历已月份为Key的map，并解析对应月份的明细
            for each(var map in monthListMap.entrySet())
            {
                var billAllData = getDoneBillAllDataHeaderData(creditCardAllData);
                billAllData.setBillMonth(js_commfuns.formatMonth(map.getKey()));
                var orderIndex = 0;
                for each(var templine in map.getValue())
                {
                    var templines = templine.split(",");
                    if (templines.length == 11) {
                        var expense = js_commfuns.getExpense();
                        expense.setId(UUID.randomUUID().toString());
                        var postDate = templines[0];
                        var transDate = templines[1];
                        var transTime = templines[2];
                        var transAdr = templines[3];
                        var zhichu = templines[4];
                        var shouru = templines[5];
                        var balance = templines[6];
                        var oppositeCard = templines[7];
                        var oppositeName = templines[8];
                        var currecy = templines[9];
                        var remark = templines[10];
                        expense.setPostDate(js_commfuns.formatDate(postDate));
                        expense.setTransDate(js_commfuns.formatDate(transDate));
                        expense.setTransAddr(transAdr);
                        if (zhichu.length() > 2) {
                            expense.setAmountMoney(stringToBigDecimal(zhichu));
                        }
                        if (shouru.length() > 2) {
                            expense.setAmountMoney(stringToBigDecimal("-"+shouru));
                        }
                        expense.setBalance(stringToBigDecimal(balance));
                        expense.setCurrencyType(convertCurr(currecy));
                        expense.setOppositeCardNo(oppositeCard);
                        expense.setNameOnOppositeCard(oppositeName);
                        expense.setRemark(remark);
                        expense.setCategory(classify(remark,expense.getAmountMoney()));
                        expense.setOrderIndex(++orderIndex);
                        expense.setCardNum(cardLastFourNum);
                        expense.setDescription(remark);
                        expense.setOppositeBank("");
                        expense.setTransChannel("");
                        expense.setTransMethod("");
                        billAllData.getShoppingSheets().add(expense);
                    }
                }
                //billDate为每个月的1号，所以拼接"-01";
                billAllData.setBillDate(js_commfuns.formatDate(js_commfuns.formatMonth(map.getKey()) + "-01"));
            }
            //如果抓取不足18个月，需要补齐未抓到月份的表头
            if (monthListMap.size() < 18) {
                logger.info("任务【｛｝】，借记卡消费明细账单中月份不足18个月，需要手动补齐", context.get(LUA_TASK_KEY));
                //获取完整的18个月的月份集合
                var monthList = js_commfuns.currentSixMonth(crawlerDate);
                //循环之前的账单，判断缺失的月份信息
                for each(var month in monthList)
                {
                    if (!monthListMap.containsKey(month)) {
                        var billAllData = getDoneBillAllDataHeaderData(creditCardAllData);
                        billAllData.setBillMonth(js_commfuns.formatMonth(month));
                        billAllData.setBillDate(js_commfuns.formatDate(js_commfuns.formatMonth(month) + "-01"));
                    }
                }
            }
            logger.info("CCBBank:taskKey=" + context.get(LUA_TASK_KEY) + " 解析第" + cardNum + "张借记卡的TXT成功!");
        } catch (e) {
            logger.info("CCBBank:taskKey=" + context.get(LUA_TASK_KEY) + " 解析第" + cardNum + "张借记卡的账单明细异常!!!");
            statCaughtExceptionByJS(context, e);
        }
    },

    //抓取帐户存款信息
    get_debit_deposit_html: function (creditCardAllData, cardNum) {
        try {
            logger.info("CCBBank:taskKey=" + context.get(Constants.LUA_TASK_KEY) + "开始抓取账户存款信息");
            var param = context.get("ccb_accountInfo_map");
            //声明Json对象，存储基本信息
            var basicInfo = context.get("jsonUserInfo");
            var cardNo = creditCardAllData.getFullCardNum();
            var individualUrl = context.get("ccb_individualUrl");
            //拼接获取账户信息的url
            var depositCardUrl = "https://ibsbjstar.ccb.com.cn" + individualUrl + "&ROW_NO=3&BRANCHID=%s&SKEY=%s&USERID=%s&ACC_NO=%s&BBANK_NAME=%s&ACC_SIGN=%s&FLAG_CARD=4&TXCODE=310800";
            depositCardUrl = String.format(depositCardUrl, basicInfo.getString("BRANCHID"), basicInfo.getString("SKEY"), basicInfo.getString("USERID"), cardNo, basicInfo.getString("BRANCHID"), cardNo);
            param.put("queryyzacc", cardNo);
            param.put("yzacc", cardNo);
            logger.info("CCB 建设银行 taskkey: {} ,抓取deposit请求开始", context.get(Constants.LUA_TASK_KEY));
            var depositCardHtml = ajax_post(depositCardUrl, param);
            logger.info("CCB 建设银行 taskkey: {} ,抓取deposit请求结束", context.get(Constants.LUA_TASK_KEY));
            storeDataToFile(context, depositCardHtml, cardNum + "_deposits.html")
            context.put("ccb_debit_deposit_html", depositCardHtml);

        } catch (e) {
            logger.info("CCBBank:taskKey=" + context.get(LUA_TASK_KEY) + " 第" + cardNum + "张借记卡的账单明细异常!!!");
            statCaughtExceptionByJS(context, e);
        }
    },

    //解析存款页面
    parse_debit_deposit_html: function (creditCardAllData, cardNum) {
        try {
            var basicInfo = context.get("jsonUserInfo");
            var depositCardHtml = context.get("ccb_debit_deposit_html");
            //如果请求返回html中包含 “0130Z1108007”或“0130Z1109001”则页面表现为 “暂不能处理您的请求，请重新登录” 则不能继续抓取，抛出异常会话超时
            if (!depositCardHtml.contains("0130Z1108007") && !depositCardHtml.contains("0130Z1109001")) {
                var deposits = new ArrayList();
                //解析获取到的html页面
                var doc = Jsoup.parse(depositCardHtml);
                logger.info("CCB 建设银行 taskkey: {} ,jsoup解析页面", context.get(Constants.LUA_TASK_KEY));
                var trs = doc.select("#result > tbody:nth-child(1)> tr");
                for (var index = 0; index < trs.size(); index++) {
                    var deposit = debit_commfuns.getCreditCardTimeDeposit();
                    var tds = trs.get(index).select("td");
                    var despoitDate = (tds.get(1).text());
                    var depositType = tds.get(2).text();
                    var currency = tds.get(3).text();
                    var balance = tds.get(4).attr("title").split(":")[1];
                    deposit.setDepositDate(js_commfuns.formatDate(despoitDate));
                    deposit.setCurrencyType(convertCurr(currency));
                    deposit.setBalance(stringToBigDecimal(balance));
                    //根据账户存款类型判断存款年月以及利率
                    debit_commfuns.judgeDepositType(depositType, tds, deposit);
                    creditCardAllData.setBalance(stringToBigDecimal(balance));
                    deposits.add(deposit);
                }
                creditCardAllData.setNameOnCard(basicInfo.getString("NAME"));
                creditCardAllData.setDeposits(deposits);
                //通过明细计算余额的公共方法
                sumBalance(creditCardAllData);
                logger.info("CCBBank:taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 获取第" + cardNum + "张借记卡的储蓄信息成功!");
            } else {
                logger.error("CCB 建设银行 taskkey: {} ,抓取deposit会话超时，页面为：{}", context.get(Constants.LUA_TASK_KEY), depositCardHtml);
                throw new BankException(BankConstants.BACR_99602_20, "会话超时，请重新登录");
            }

        } catch (e) {
            logger.info("CCBBank:taskKey=" + context.get(LUA_TASK_KEY) + " 第" + cardNum + "张借记卡的存款信息异常:" + e);
            statCaughtExceptionByJS(context, e);
        }
    },

    judgeDepositType: function (depositType, tds, deposit) {
        if (depositType.contains("活期储蓄")) {
            deposit.setDepositType(depositType);
        } else if (depositType.contains("整存整取")) {
            deposit.setDepositType("整存整取");
            //目前整存整取是有利息信息的 后续可能出现多种情况
            var insertScript = tds.get(2).select("script").first().data();
            if (StringUtils.isNotBlank(insertScript)) {
                var insert = String.valueOf(Double.parseDouble(js_commfuns.formatNumber("1.35000")) / 100).substring(0, 6);
                deposit.setInterest(stringToBigDecimal(insert));
            }
            //针对三个月,三年等情况进行的处理
            var despoitTypeTime = depositType.split(" ")[1];
            var despoitDate = deposit.getDepositDate();
            if (despoitTypeTime.contains("月")) {
                var index = despoitTypeTime.indexOf("个");
                var monthNum = despoitTypeTime.substring(0, index);
                var period = debit_commfuns.basicConvert(monthNum);
                var duedate = debit_commfuns.addDueDate("MONTH", period, despoitDate);
                deposit.setPeriod(period);
                deposit.setPeriodUnit("MONTH");
                deposit.setDueDate(duedate);
            } else {
                if (despoitTypeTime.contains("年")) {
                    var index = despoitTypeTime.indexOf("年");
                    var yearNum = despoitTypeTime.substring(0, index);
                    if (yearNum.equals("半")) {
                        var period = 6;
                        var duedate = debit_commfuns.addDueDate("MONTH", period, despoitDate);
                        deposit.setPeriod(period);
                        deposit.setPeriodUnit("MONTH");
                        deposit.setDueDate(duedate);
                    } else {
                        var period = debit_commfuns.basicConvert(yearNum);
                        var duedate = debit_commfuns.addDueDate("YEAR", period, despoitDate);
                        deposit.setPeriod(period);
                        deposit.setPeriodUnit("YEAR");
                        deposit.setDueDate(duedate);
                    }
                }
            }
        }
    },

    basicConvert: function (num) {
        var intNum = 0;
        if ("一".equals(num)) {
            intNum = 1;
        } else if ("二".equals(num)) {
            intNum = 2;
        } else if ("三".equals(num)) {
            intNum = 3;
        } else if ("四".equals(num)) {
            intNum = 4;
        } else if ("五".equals(num)) {
            intNum = 5;
        } else if ("六".equals(num)) {
            intNum = 6;
        } else if ("七".equals(num)) {
            intNum = 7;
        } else if ("八".equals(num)) {
            intNum = 8;
        } else if ("九".equals(num)) {
            intNum = 9;
        } else if ("十".equals(num)) {
            intNum = 10;
        } else if ("十一".equals(num)) {
            intNum = 11;
        } else if ("十二".equals(num)) {
            intNum = 12;
        }
        return intNum;
    },

    addDueDate: function (flag, period, depositDate) {
        //即  2017-07-03
        depositDate = yyyy_MM_dd_PARSER.format(depositDate);
        var yearMonthDay = depositDate.split("-");
        var due_date = "";
        if ("YEAR".equals(flag)) {
            var newYear = Integer.parseInt(yearMonthDay[0]) + period;
            due_date = newYear + "-" + yearMonthDay[1] + "-" + yearMonthDay[2];
        }
        if ("MONTH".equals(flag)) {
            var newMonth = Integer.parseInt(yearMonthDay[1]) + period;
            if (newMonth > 12) {
                newMonth = newMonth % 12;
                var newYear = Integer.parseInt(yearMonthDay[0]) + 1;
                yearMonthDay[0] = Integer.toString(newYear);
            }
            var newMonthString = "";
            if (Integer.parseInt(newMonth).toString().length == 1) {
                newMonthString = "0" + newMonth;
            } else {
                newMonthString = "" + newMonth;
            }
            due_date = yearMonthDay[0] + "-" + newMonthString + "-" + yearMonthDay[2];
        }
        return yyyy_MM_dd_PARSER.parse(due_date);
    },

    //获取借记卡的18个月的开始和截止时间
    getStartAndEndDate: function () {
        var dateMap = new LinkedHashMap();
        var format = new SimpleDateFormat("yyyyMMdd");
        var calendar = Calendar.getInstance();
        var endDate = format.format(calendar.getTime());
        calendar.add(Calendar.MONTH, -17);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        var beginDate = format.format(calendar.getTime());
        dateMap.put("beginDate", beginDate);
        dateMap.put("endDate", endDate);
        return dateMap;
    },

    //获取一个存款信息页面
    getCreditCardTimeDeposit: function () {
        var creditCardTimeDeposit = new CreditCardTimeDeposit();
        creditCardTimeDeposit.setBalance(null);
        creditCardTimeDeposit.setInterest(null);
        creditCardTimeDeposit.setPeriod(null);
        return creditCardTimeDeposit;
    },
}

/**
 * 通用方法
 */
var js_commfuns = {

    checkFrameStatus: function () {
        var loginStr = getLoginParams(context)[0];
        //获取登录页面
        logger.info("CCB taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 开始登录");
        //通过js方法获取登录框所在frame的id ，为防止网站修改id造成获取不到frame的影响
        var frameId = lua_commfuns.getFrameId();
        //等待页面渲染完全，最多等待10s
        var contentWillBeCheckedFunc = function () {
            Thread.sleep(1000);
            return frame_is_exist_by_id("USERID", frameId);
        }
        var isCorrectFunc = function (contentWillBeChecked) {
            return contentWillBeChecked
        }
        context.put("frameId", frameId);
        var time = new Date().getTime();
        var data1 = new HashMap();
        data1.put("COPY_USERID", loginStr);
        data1.put("QR_CODE_ID", "undefined");
        //发送post请求，校验用户名信息是否正确
        var html1 = ajax_post("https://ibsbjstar.ccb.com.cn/CCBIS/B2CMainPlat_00?SERVLET_NAME=B2CMainPlat_00&CCB_IBSVersion=V6&PT_STYLE=1&PT_LANGUAGE=CN&TXCODE=N20008&SKEY=&time=" + time, data1);
        //如果返回页面含有如下代码，为用户名不存在，请核对用户名，此处作为参考，在后面有处理
        /*if (html1.contains("YDCA04310001")) {
            logger.info("ccb 建设银行 taskkey:{} , 请核对用户名", context.get(Constants.LUA_TASK_KEY));
        }*/
        //如果repeater状态为false，则认为页面加载不完整，保存页面并抛登录超时异常
        return repeater(contentWillBeCheckedFunc, isCorrectFunc, 10);
    },

    getFrameFlag: function (loginedHtml) {
        var frameFlag = "";
        if (loginedHtml.contains("mainfrm1")) {
            frameFlag = "mainfrm1";
        } else {
            frameFlag = "mainfrm";
        }
        return frameFlag;
    },

    getLoginErrorMsg: function (loginedHtml, smsHtml) {
        //var loginedHtml = loginResult.get("html")
        var errorMsg = Jsoup.parse(loginedHtml).select("#error_main > div.failed_span > div > div > div:nth-child(2) > table > tbody > tr > td:nth-child(1)");
        if (errorMsg != null && errorMsg.size() > 0) {
            errorMsg = errorMsg.get(0).text();
        }


        //如果页面包含以下信息，则为尚未尚未注册或无此用户
        if (loginedHtml.contains("您输入的信息有误，请尝试用以下方式解决：") || loginedHtml.contains("未查询到相应客户信息") || loginedHtml.contains("YDCAP101NM03")) {
            return "未查询到相应客户信息";
        }

        else if (loginedHtml.contains("您的登录信息不正常")) {
            return "您的登录信息不正常";
        }
        else if (loginedHtml.contains("0130Z1108206") || loginedHtml.contains("未能处理您的请求")) {
            return "未能处理您的请求";
        }
        //如果页面包含以下信息，则为用户名密码错误
        else if (errorMsg.contains("YPWAP101NM07") || loginedHtml.contains("您输入的登录密码不正确")) {
            return "您输入的登录密码不正确。";
        }

        //如果页面包含以下信息，则为用户名密码错误次数超限
        else if (loginedHtml.contains("YPWAP101NM08") || loginedHtml.contains("0130Z1101003")) {
            return "您输入的密码错误次数已超限。请在次日重试或重置。";
        }

        else if (errorMsg.contains("您已暂停使用网银服务功能") || loginedHtml.contains("您已暂停使用网银服务功能")) {
            return "您已暂停使用网银服务功能"
        }

        //页面显示：无法找到该网页
        else if (loginedHtml.contains("无法找到该网页")) {
            return "登录超时";
        }
        //如果页面包含以下信息，则视为登录超时
        else if (loginedHtml.contains("请您在浏览器中清理并设置接受服务器下传的Cookie") || loginedHtml.contains("0130Z1108006")) {
            return "尚未注册或无此用户";
        }
        //如果页面包含以下信息，则视为会话超时
        // 0130Z1108007-->暂时未能处理您的请求
        // 0130Z1108214-->未能处理您的请求
        else if (loginedHtml.contains("暂时未能处理您的请求") || loginedHtml.contains("0130Z1108007") || loginedHtml.contains("0130Z1108214")) {
            return "暂时未能处理您的请求,请重新登录";
        }
        //对不起，您的交易过于频繁，请稍侯再做
        else if (loginedHtml.contains("对不起，您的交易过于频繁，请稍侯再做")) {
            return "对不起，您的交易过于频繁，请稍侯再做"
        }
        //如果页面包含以下信息，则为"您登录密码已超过六个月未修改，为了您网银的安全使用，请修改登录密码"
        else if (loginedHtml.contains("建议您将密码设置为")) {
            return "您登录密码已超过六个月未修改，为了您网银的安全使用，请修改登录密码";
        }
        //如果页面包含以下信息，则视为"未设置网上银行登录密码，请到官网设置"
        else if (loginedHtml.contains("您尚未设置网上银行登录密码")) {
            return "您尚未设置网上银行登录密码";
        }
        //如果页面包含以下信息，则视为登录方式错误
        else if (loginedHtml.contains("该客户只能以用户名登录")) {
            return "该客户只能以用户名登录";
        }
        //如果页面包含以下信息，则视为"您的个人网银已通过手机短信申请冻结"
        else if (loginedHtml.contains("您的个人网银已通过手机短信申请冻结")) {
            return "您的个人网银已通过手机短信申请冻结";
        }
        //如果页面包含以下信息，则视为"没有查询到您的用户信息，请先尝试官网登陆或与客服联系"
        else if (loginedHtml.contains("0130Z1108009") || loginedHtml.contains("没有查询到您的用户信息")) {
            return "尚未注册或无此用户";
        }
        //如果页面包含以下信息，则视为登录方式错误
        else if (loginedHtml.contains("您是高端版网银客户，请从高端版专用入口登录")) {
            return "您是高端版网银客户，请从高端版专用入口登录";
        } else if (loginedHtml.contains("中国建设银行网上银行个人登录验证")) {
            return "中国建设银行网上银行个人登录验证";
        }
        //如果页面包含以下信息，则视为卡片未激活，请到官网激活
        else if (loginedHtml.contains(">客户激活<")) {
            return "卡片未激活";
        }
        //如果页面包含以下信息，则视为系统繁忙
        else if (loginedHtml.contains("Hypertext Transfer Protocol")) {
            return "Hypertext Transfer Protocol";
        }
        //如果页面包含以下信息，则视为系统繁忙
        else if (loginedHtml.contains("请设置网上银行交易密码")) {
            return "请设置网上银行交易密码";
        }
        else if (loginedHtml.contains("您输入的信息含特殊字符，请重新输入")) {
            return "您输入的信息含特殊字符，请重新输入。";
        }

        else if (smsHtml.contains("暂时未能处理您的请求，请重新登录") && loginedHtml.contains("请尽量使用专用电脑操作网上银行，并定期更新操作系统安全补丁和杀毒软件") || loginedHtml.contains("您已较长时间未进行操作，为保护您的资金安全，系统已自动退出")) {
            return "登录超时";
        }

        else if (loginedHtml.contains("您已暂停网银服务！如您要恢复网银服务，请正确输入账户信息和回答您的私密问题")) {
            return "您已暂停使用网银服务功能";
        }
        return "";
    },


    //获取到主页信息
    get_main_html: function () {
        try {
            logger.info("任务【{}】建设借记卡，开始获取登录成功后得基本请求信息", context.get(LUA_TASK_KEY));
            var html = get_html();
            storeDataToFile(context, html, "mainHtml_.html")
            context.put("ccb_main_html", html);
            logger.info("任务【{}】建设银行，登录后跳转主页成功！", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,抓取主页信息异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }

    },

    //解析主页信息,解析出来的参数用于之后的请求
    parse_main_html: function () {
        logger.info("任务【{}】，建设银行开始解析主页信息的请求参数", context.get(LUA_TASK_KEY));
        var html = context.get("ccb_main_html")
        //通过正则表达式获取到userInfo信息，userInfo信息格式为
        var userInfo = getGroupByIndex("var DAT_USERBASE=_DAT_USERBASE = (\\{[\\s\\S]*?\\})", html, 1).replace("\\", "");
        //如果userInfo信息为空，则获取基础信息失败，停止抓取
        if (userInfo.equals("") || userInfo == null) {
            logger.error("任务【{}】，建设银行解析userinfo信息失败，停止抓取", context.get(LUA_TASK_KEY));
            throw new BankException(BankConstants.BALO_23001_10, "基本请求信息获取失败，停止抓取");
        }
        //获取登录url信息，url信息格式如下
        var urlInfo = getGroupByIndex("var DAT_ENVBASE=_DAT_ENVBASE = (\\{[\\s\\S]*?\\})", html, 1).replace("\\", "");
        //如果urlInfo信息为空，则获取基础信息失败，停止抓取
        if (urlInfo.equals("") || urlInfo == null) {
            logger.error("任务【{}】，建设银行解析的登录url信息失败，停止抓取", context.get(LUA_TASK_KEY));
            throw new BankException(BankConstants.BALO_23001_10, "基本请求信息获取失败，停止抓取");
        }
        var jsonUserInfo = JSON.parseObject(userInfo);
        var jsonUrlInfo = JSON.parseObject(urlInfo);
        context.put("jsonUserInfo", jsonUserInfo);
        context.put("jsonUrlInfo", jsonUrlInfo);

        var individualUrl = jsonUrlInfo.getString("P1ACTION");
        //若没有获取到用户的Url则抛异常
        if (individualUrl.equals("") || individualUrl == null) {
            logger.error("CCB taskKey=" + context.get(Constants.LUA_TASK_KEY) + " 基础请求信息获取失败,停止抓取");
            throw new BankException(BankConstants.BACR_20306_30, " 基本请求信息获取失败,停止抓取");
        }
        context.put("ccb_individualUrl", individualUrl);
        logger.info("任务【{}】，建设银行解析基本请求信息成功！", context.get(LUA_TASK_KEY));
    },
    //抓信用卡列表页
    get_credit_card_list_html: function () {
        try {
            logger.info("任务【{}】，建设银行，开始抓取信用卡列表信息", context.get(LUA_TASK_KEY));
            var jsonUserInfo = context.get("jsonUserInfo");
            var individualUrl = context.get("ccb_individualUrl")
            //拼接查询信用卡列表url
            var balanceUrl = "https://ibsbjstar.ccb.com.cn" + individualUrl + "&USERID=%s&BRANCHID=%s&SKEY=%s&TXCODE=XE1110&TYPE_FLAG=1";
            balanceUrl = String.format(balanceUrl, jsonUserInfo.getString("USERID"), jsonUserInfo.getString("BRANCHID"), jsonUserInfo.getString("SKEY"));
            //获取信用卡列表页面
            var cardListHtml = ajax_get(balanceUrl);
            //保存页面到cardList.html
            storeDataToFile(context, cardListHtml, "cardList.html")
            //放到上下文中，抓取是用到此页面
            context.put("creditCardListHtml", cardListHtml);
            logger.info("任务【{}】，建设银行，抓取信用卡列表信息完成！", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,建设银行，抓取信用卡列表异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },


    //获取基本请求信息
    get_base_info_url: function () {
        try {
            logger.info("任务【{}】，建设银行开始获取账基本信息", context.get(LUA_TASK_KEY));
            var userInfo = context.get("jsonUserInfo");
            var individualUrl = context.get("ccb_individualUrl");
            //拼接获取卡信息参数的url
            var cardHomeUrl = "https://ibsbjstar.ccb.com.cn" + individualUrl + "&USERID=%s&BRANCHID=%s&SKEY=%s&TXCODE=310103";
            cardHomeUrl = String.format(cardHomeUrl, userInfo.getString("USERID"), userInfo.getString("BRANCHID"), userInfo.getString("SKEY"));
            //发送请求并保存页面
            var html = ajax_get(cardHomeUrl);
            storeDataToFile(context, html, "cardCategory.html")
            context.put("ccb_cardCategory", html);
            logger.info("任务【{}】，建设银行获取账基本完成！", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,建设银行，建设银行获取账基本异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    parse_base_url_info: function () {
        try {
            logger.info("任务【{}】,建设银行开始解析账户基本信息中的请求参数", context.get(LUA_TASK_KEY));
            var html = context.get("ccb_cardCategory");
            //获取页面hidden的一些参数 接下来的请求需要
            var doc = Jsoup.parse(html);
            var elements = doc.select("#jhform > input");
            var map = new LinkedHashMap();
            //解析jhform中的所有input中参数信息
            if (elements !== null && elements.size() > 0) {
                logger.info("任务【{}】,填充accountInfo账户信息的请求参数获取", context.get(LUA_TASK_KEY));
                for (var i = 0; i < elements.size(); i++) {
                    var key = elements.get(i).attr("name");
                    var value = elements.get(i).attr("value");
                    map.put(key, value);
                }
            } else {
                logger.error("任务【{}】, accountInfo账户信息的请求参数获取，失败为空，继续抓取", context.get(LUA_TASK_KEY));
            }
            context.put("ccb_accountInfo_map", map);
            logger.info("任务【{}】,建设银行解析账户基本信息中的请求参数完成", context.get(LUA_TASK_KEY));
        } catch (e) {
            logger.error("任务【{}】,建设银行解析账户基本信息中的请求参数异常：{}", context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    },

    //创建一个消费明细对象
    getExpense: function () {
        var expense = new Expense();
        expense.setAmountMoney(null);
        expense.setBalance(null);
        return expense;
    },

    //日期转换
    formatMonth: function (dateStr) {
        if (dateStr == null || dateStr.trim().equals("")) {
            return "";
        }
        dateStr = getGroupByIndex("(\\d+)", dateStr, 1);
        var d = null;
        try {
            if (dateStr.length() == 6) {
                d = DateUtils.parseDate(dateStr, "yyyyMM");
            } else {
                d = DateUtils.parseDate(dateStr, "yyyyMMdd");
            }
        } catch (e) {
            // statCaughtExceptionByJS(context, e);
            logger.error("ccb taskKey=" + context.get(Constants.LUA_TASK_KEY) + "解析日期格式出错" + dateStr, e);
        }
        dateStr = DateFormatUtils.format(d, "yyyy-MM");
        return dateStr;
    },

    //日期转换
    formatDate: function (dateStr) {
        if (dateStr == null || dateStr.trim().equals("")) {
            return null;
        }
        var d = "";
        dateStr = findAll("(\\d+)", dateStr, 1);
        for each( var str in dateStr)
        {
            d = d + str;
        }
        if (d == "") {
            return null
        }
        try {
            d = DateUtils.parseDate(d, "yyyyMMdd");
        } catch (e) {
            // statCaughtExceptionByJS(context, e);
            logger.error("ccb taskKey=" + context.get(Constants.LUA_TASK_KEY) + "解析日期格式出错" + dateStr, e);
        }
        return d;
    },


    formatNumber: function (numberStr) {
        if (StringUtils.isBlank(numberStr)) {
            return "0";
        }
        numberStr = getGroupByIndex("(-*\\d+\\.*\\d*)", numberStr, 1);
        return numberStr;
    },

    getInstallment: function () {
        var installment = new Installment();
        installment.setAmountMoney(null);
        installment.setHandingFee(null);
        installment.setTransferFee(null);
        return installment;
    },

    getDatestr: function (dateStr) {
        return getGroupByIndex("(\\d+)", dateStr, 1);
    },

    get_now_date: function () {
        var cal = Calendar.getInstance();
        var sdf = new SimpleDateFormat("yyyyMM");
        var dateString = sdf.format(cal.getTime());
        return dateString.substring(0, 6);
    },

    currentSixMonth: function (date) {
        var cal = Calendar.getInstance();
        var sdf = new SimpleDateFormat("yyyyMM");
        var monthList = new ArrayList();
        cal.setTime(sdf.parse(date));
        for (var i = 0; i < 18; i++) {
            var dateString = sdf.format(cal.getTime());
            monthList.add(dateString.substring(0, 6));
            cal.add(Calendar.MONTH, -1);
        }
        return monthList;
    }


}


/**
 * 建设lua方法
 */
var lua_commfuns = {

    //输入用户名密码
    input_username_password: function (userid, password) {
        var map = new HashMap();
        map.put("method", "input_username_password");
        map.put("userid", userid);
        map.put("password", password);
        return sendAndReceive(map);
    },

    //点击登录按钮
    click_login_button: function () {
        var map = new HashMap();
        map.put("method", "click_login_button");
        return sendAndReceive(map);
    },

    //是否需要图片验证码
    is_need_img_code: function () {
        var map = new HashMap();
        map.put("method", "is_need_img_code");
        return sendAndReceive(map);
    },

    //输入图片验证码
    input_img_code: function (imgCode) {
        var map = new HashMap();
        map.put("method", "input_img_code");
        map.put("imgCode", imgCode);
        return sendAndReceive(map);
    },

    //获取指定id的frame页面
    get_frame_html_by_id: function (frameid) {
        var map = new HashMap();
        map.put("method", "get_frame_html_by_id");
        map.put("frameid", frameid);
        return sendAndReceive(map);
    },

    //输入答案
    setAnster: function (anster, fangWei) {
        var map = new HashMap();
        map.put("method", "setAnster");
        map.put("anster", "anster");
        return sendAndReceive(map);
    },

    //点击问题页面确定
    clickButon: function () {
        var map = new HashMap();
        map.put("method", "clickButon");
        return sendAndReceive(map);
    },

    //获取短信输入内容
    getSmsInputResult: function (frameFlag) {
        var map = new LinkedHashMap();
        map.put("method", "getSmsInputResult");
        map.put("frameFlag", frameFlag);
        return sendAndReceive(map);
    },

    clickSmsButton: function (frameFlag) {
        var map = new LinkedHashMap();
        map.put("method", "clickSmsButton");
        map.put("frameFlag", frameFlag);
        return sendAndReceive(map);
    },

    getSrcUrl2: function (spanIndex, values) {
        var map = new LinkedHashMap();
        map.put("method", "get_src_url2");
        map.put("values", values);
        map.put("spanIndex", spanIndex);
        return sendAndReceive(map);
    },

    setCCBQueryCondition: function (START_DATE, END_DATE, index) {
        var map = new LinkedHashMap();
        map.put("method", "set_CCB_query_condition");
        map.put("START_DATE", START_DATE);
        map.put("END_DATE", END_DATE);
        map.put("index", index);
        return sendAndReceive(map);
    },

    isDownload: function (index) {
        var map = new LinkedHashMap();
        map.put("method", "CCB_isNeedDownload");
        map.put("index", index);
        return sendAndReceive(map);
    },

    getPostParams: function (startDate, endDate, index) {
        var map = new LinkedHashMap();
        map.put("method", "CCB_post_params");
        map.put("startDate", startDate);
        map.put("endDate", endDate);
        map.put("index", index);
        return sendAndReceive(map);
    },

    goToSrcUrl: function (urlIndex) {
        var map = new LinkedHashMap();
        map.put("method", "goto_src_url");
        map.put("urlIndex", urlIndex);
        return sendAndReceive(map);
    },

    ajax_post_dif_ie: function (url, postdata) {
        var map = new LinkedHashMap();
        var sb = new StringBuffer();
        for each(var key in postdata.keySet())
        {
            if (!"index".equals(key)) {
                sb.append(key + "=" + postdata.get(key) + "&");
            }
        }
        data = "";
        if (sb.length() > 0) {
            data = sb.substring(0, sb.length() - 1);
        }
        data1 = data;
        map.put("url", url);
        map.put("method", "ajax_post_dif_ie");
        map.put("data", data1);
        map.put("index", postdata.get("index"));
        return sendAndReceive(map);
    },

    getFrameId: function () {
        var map = new LinkedHashMap();
        map.put("method", "getFrameId");
        return sendAndReceive(map);
    },
    saveIframeHtmlAndImage: function (frameIds, name) {
        var map = new HashMap();
        map.put("method", "saveIframeHtmlAndImage");
        map.put("frameIds", frameIds);
        map.put("name", name);
        return sendAndReceive(map);
    },
    saveHtmlAndImage: function (name) {
        var map = new HashMap();
        map.put("method", "saveHtmlAndImage");
        map.put("name", name);
        return sendAndReceive(map);
    },

    click_sms_back_btn:function (frameFlag) {
        var map = new HashMap();
        map.put("method", "click_sms_back_button");
        map.put("frameFlag", frameFlag);
        return sendAndReceive(map);
    }


}